@@ -182,11 +182,16 @@ impl<T, A: Allocator> VecDeque<T, A> {
182182 unsafe { ptr:: read ( self . ptr ( ) . add ( off) ) }
183183 }
184184
185- /// Writes an element into the buffer, moving it.
185+ /// Writes an element into the buffer, moving it and returning a pointer to it.
186+ /// # Safety
187+ ///
188+ /// May only be called if `off < self.capacity()`.
186189 #[ inline]
187- unsafe fn buffer_write ( & mut self , off : usize , value : T ) {
190+ unsafe fn buffer_write ( & mut self , off : usize , value : T ) -> & mut T {
188191 unsafe {
189- ptr:: write ( self . ptr ( ) . add ( off) , value) ;
192+ let ptr = self . ptr ( ) . add ( off) ;
193+ ptr:: write ( ptr, value) ;
194+ & mut * ptr
190195 }
191196 }
192197
@@ -1888,16 +1893,34 @@ impl<T, A: Allocator> VecDeque<T, A> {
18881893 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
18891894 #[ track_caller]
18901895 pub fn push_front ( & mut self , value : T ) {
1896+ let _ = self . push_front_mut ( value) ;
1897+ }
1898+
1899+ /// Prepends an element to the deque, returning a reference to it.
1900+ ///
1901+ /// # Examples
1902+ ///
1903+ /// ```
1904+ /// #![feature(push_mut)]
1905+ /// use std::collections::VecDeque;
1906+ ///
1907+ /// let mut d = VecDeque::from([1, 2, 3]);
1908+ /// let x = d.push_front_mut(8);
1909+ /// *x -= 1;
1910+ /// assert_eq!(d.front(), Some(&7));
1911+ /// ```
1912+ #[ unstable( feature = "push_mut" , issue = "135974" ) ]
1913+ #[ track_caller]
1914+ #[ must_use = "if you don't need a reference to the value, use `VecDeque::push_front` instead" ]
1915+ pub fn push_front_mut ( & mut self , value : T ) -> & mut T {
18911916 if self . is_full ( ) {
18921917 self . grow ( ) ;
18931918 }
18941919
18951920 self . head = self . wrap_sub ( self . head , 1 ) ;
18961921 self . len += 1 ;
1897-
1898- unsafe {
1899- self . buffer_write ( self . head , value) ;
1900- }
1922+ // SAFETY: We know that self.head is within range of the deque.
1923+ unsafe { self . buffer_write ( self . head , value) }
19011924 }
19021925
19031926 /// Appends an element to the back of the deque.
@@ -1916,12 +1939,33 @@ impl<T, A: Allocator> VecDeque<T, A> {
19161939 #[ rustc_confusables( "push" , "put" , "append" ) ]
19171940 #[ track_caller]
19181941 pub fn push_back ( & mut self , value : T ) {
1942+ let _ = self . push_back_mut ( value) ;
1943+ }
1944+
1945+ /// Appends an element to the back of the deque, returning a reference to it.
1946+ ///
1947+ /// # Examples
1948+ ///
1949+ /// ```
1950+ /// #![feature(push_mut)]
1951+ /// use std::collections::VecDeque;
1952+ ///
1953+ /// let mut d = VecDeque::from([1, 2, 3]);
1954+ /// let x = d.push_back_mut(9);
1955+ /// *x += 1;
1956+ /// assert_eq!(d.back(), Some(&10));
1957+ /// ```
1958+ #[ unstable( feature = "push_mut" , issue = "135974" ) ]
1959+ #[ track_caller]
1960+ #[ must_use = "if you don't need a reference to the value, use `VecDeque::push_back` instead" ]
1961+ pub fn push_back_mut ( & mut self , value : T ) -> & mut T {
19191962 if self . is_full ( ) {
19201963 self . grow ( ) ;
19211964 }
19221965
1923- unsafe { self . buffer_write ( self . to_physical_idx ( self . len ) , value ) }
1966+ let len = self . len ;
19241967 self . len += 1 ;
1968+ unsafe { self . buffer_write ( self . to_physical_idx ( len) , value) }
19251969 }
19261970
19271971 #[ inline]
@@ -2007,7 +2051,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
20072051 ///
20082052 /// # Panics
20092053 ///
2010- /// Panics if `index` is strictly greater than deque's length
2054+ /// Panics if `index` is strictly greater than the deque's length.
20112055 ///
20122056 /// # Examples
20132057 ///
@@ -2029,7 +2073,37 @@ impl<T, A: Allocator> VecDeque<T, A> {
20292073 #[ stable( feature = "deque_extras_15" , since = "1.5.0" ) ]
20302074 #[ track_caller]
20312075 pub fn insert ( & mut self , index : usize , value : T ) {
2076+ let _ = self . insert_mut ( index, value) ;
2077+ }
2078+
2079+ /// Inserts an element at `index` within the deque, shifting all elements
2080+ /// with indices greater than or equal to `index` towards the back, and
2081+ /// returning a reference to it.
2082+ ///
2083+ /// Element at index 0 is the front of the queue.
2084+ ///
2085+ /// # Panics
2086+ ///
2087+ /// Panics if `index` is strictly greater than the deque's length.
2088+ ///
2089+ /// # Examples
2090+ ///
2091+ /// ```
2092+ /// #![feature(push_mut)]
2093+ /// use std::collections::VecDeque;
2094+ ///
2095+ /// let mut vec_deque = VecDeque::from([1, 2, 3]);
2096+ ///
2097+ /// let x = vec_deque.insert_mut(1, 5);
2098+ /// *x += 7;
2099+ /// assert_eq!(vec_deque, &[1, 12, 2, 3]);
2100+ /// ```
2101+ #[ unstable( feature = "push_mut" , issue = "135974" ) ]
2102+ #[ track_caller]
2103+ #[ must_use = "if you don't need a reference to the value, use `VecDeque::insert` instead" ]
2104+ pub fn insert_mut ( & mut self , index : usize , value : T ) -> & mut T {
20322105 assert ! ( index <= self . len( ) , "index out of bounds" ) ;
2106+
20332107 if self . is_full ( ) {
20342108 self . grow ( ) ;
20352109 }
@@ -2042,16 +2116,16 @@ impl<T, A: Allocator> VecDeque<T, A> {
20422116 unsafe {
20432117 // see `remove()` for explanation why this wrap_copy() call is safe.
20442118 self . wrap_copy ( self . to_physical_idx ( index) , self . to_physical_idx ( index + 1 ) , k) ;
2045- self . buffer_write ( self . to_physical_idx ( index) , value) ;
20462119 self . len += 1 ;
2120+ self . buffer_write ( self . to_physical_idx ( index) , value)
20472121 }
20482122 } else {
20492123 let old_head = self . head ;
20502124 self . head = self . wrap_sub ( self . head , 1 ) ;
20512125 unsafe {
20522126 self . wrap_copy ( old_head, self . head , index) ;
2053- self . buffer_write ( self . to_physical_idx ( index) , value) ;
20542127 self . len += 1 ;
2128+ self . buffer_write ( self . to_physical_idx ( index) , value)
20552129 }
20562130 }
20572131 }
0 commit comments