@@ -2503,6 +2503,104 @@ impl<T, A: Allocator> Vec<T, A> {
2503
2503
Ok ( ( ) )
2504
2504
}
2505
2505
2506
+ /// Appends an element to the back of a collection, returning a reference to it.
2507
+ ///
2508
+ /// # Panics
2509
+ ///
2510
+ /// Panics if the new capacity exceeds `isize::MAX` _bytes_.
2511
+ ///
2512
+ /// # Examples
2513
+ ///
2514
+ /// ```
2515
+ /// #![feature(push_mut)]
2516
+ ///
2517
+ /// # #[allow(unused)]
2518
+ /// #[derive(PartialEq, Eq, Debug)]
2519
+ /// struct Item { identifier: &'static str, count: usize }
2520
+ ///
2521
+ /// impl Default for Item {
2522
+ /// fn default() -> Self {
2523
+ /// return Self { identifier: "stone", count: 64 }
2524
+ /// }
2525
+ /// }
2526
+ ///
2527
+ /// let mut items = vec![];
2528
+ ///
2529
+ /// // We can mutate the just-pushed value without having to fetch it again
2530
+ /// for count in [15, 35, 61] {
2531
+ /// let item = items.push_mut(Item::default());
2532
+ /// item.count = count;
2533
+ /// }
2534
+ ///
2535
+ /// assert_eq!(
2536
+ /// items,
2537
+ /// [Item { identifier: "stone", count: 15 }, Item { identifier: "stone", count: 35 }, Item { identifier: "stone", count: 61 }]
2538
+ /// );
2539
+ /// ```
2540
+ ///
2541
+ /// # Time complexity
2542
+ ///
2543
+ /// Takes amortized *O*(1) time. If the vector's length would exceed its
2544
+ /// capacity after the push, *O*(*capacity*) time is taken to copy the
2545
+ /// vector's elements to a larger allocation. This expensive operation is
2546
+ /// offset by the *capacity* *O*(1) insertions it allows.
2547
+ #[ cfg( not( no_global_oom_handling) ) ]
2548
+ #[ inline]
2549
+ #[ unstable( feature = "push_mut" , issue = "135974" ) ]
2550
+ #[ track_caller]
2551
+ #[ must_use = "if you don't need a reference to the value, use Vec::push instead" ]
2552
+ pub fn push_mut ( & mut self , value : T ) -> & mut T {
2553
+ // Inform codegen that the length does not change across grow_one().
2554
+ let len = self . len ;
2555
+ // This will panic or abort if we would allocate > isize::MAX bytes
2556
+ // or if the length increment would overflow for zero-sized types.
2557
+ if len == self . buf . capacity ( ) {
2558
+ self . buf . grow_one ( ) ;
2559
+ }
2560
+ unsafe {
2561
+ let end = self . as_mut_ptr ( ) . add ( len) ;
2562
+ ptr:: write ( end, value) ;
2563
+ self . len = len + 1 ;
2564
+ // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference.
2565
+ & mut * end
2566
+ }
2567
+ }
2568
+
2569
+ /// Appends an element and returns a reference to it if there is sufficient spare capacity, otherwise an error is returned
2570
+ /// with the element.
2571
+ ///
2572
+ /// Unlike [`push_mut`] this method will not reallocate when there's insufficient capacity.
2573
+ /// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity.
2574
+ ///
2575
+ /// [`push_mut`]: Vec::push_mut
2576
+ /// [`reserve`]: Vec::reserve
2577
+ /// [`try_reserve`]: Vec::try_reserve
2578
+ ///
2579
+ /// # Time complexity
2580
+ ///
2581
+ /// Takes *O*(1) time.
2582
+ //
2583
+ // Since there's currently no way to have multiple unstable attributes on the same item, I compromised.
2584
+ // Uncomment/delete the respective attribute when its respective issue stabilizes, since this falls under both.
2585
+ //
2586
+ #[ unstable( feature = "push_mut" , issue = "135974" ) ]
2587
+ // #[unstable(feature = "vec_push_within_capacity", issue = "100486")]
2588
+ //
2589
+ #[ inline]
2590
+ #[ must_use = "if you don't need a reference to the value, use Vec::push_within_capacity instead" ]
2591
+ pub fn push_mut_within_capacity ( & mut self , value : T ) -> Result < & mut T , T > {
2592
+ if self . len == self . buf . capacity ( ) {
2593
+ return Err ( value) ;
2594
+ }
2595
+ unsafe {
2596
+ let end = self . as_mut_ptr ( ) . add ( self . len ) ;
2597
+ ptr:: write ( end, value) ;
2598
+ self . len += 1 ;
2599
+ // SAFETY: We just wrote a value to the pointer that will live the lifetime of the reference.
2600
+ Ok ( & mut * end)
2601
+ }
2602
+ }
2603
+
2506
2604
/// Removes the last element from a vector and returns it, or [`None`] if it
2507
2605
/// is empty.
2508
2606
///
0 commit comments