@@ -182,11 +182,16 @@ impl<T, A: Allocator> VecDeque<T, A> {
182
182
unsafe { ptr:: read ( self . ptr ( ) . add ( off) ) }
183
183
}
184
184
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()`.
186
189
#[ 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 {
188
191
unsafe {
189
- ptr:: write ( self . ptr ( ) . add ( off) , value) ;
192
+ let ptr = self . ptr ( ) . add ( off) ;
193
+ ptr:: write ( ptr, value) ;
194
+ & mut * ptr
190
195
}
191
196
}
192
197
@@ -1888,16 +1893,34 @@ impl<T, A: Allocator> VecDeque<T, A> {
1888
1893
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1889
1894
#[ track_caller]
1890
1895
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 {
1891
1916
if self . is_full ( ) {
1892
1917
self . grow ( ) ;
1893
1918
}
1894
1919
1895
1920
self . head = self . wrap_sub ( self . head , 1 ) ;
1896
1921
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) }
1901
1924
}
1902
1925
1903
1926
/// Appends an element to the back of the deque.
@@ -1916,12 +1939,33 @@ impl<T, A: Allocator> VecDeque<T, A> {
1916
1939
#[ rustc_confusables( "push" , "put" , "append" ) ]
1917
1940
#[ track_caller]
1918
1941
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 {
1919
1962
if self . is_full ( ) {
1920
1963
self . grow ( ) ;
1921
1964
}
1922
1965
1923
- unsafe { self . buffer_write ( self . to_physical_idx ( self . len ) , value ) }
1966
+ let len = self . len ;
1924
1967
self . len += 1 ;
1968
+ unsafe { self . buffer_write ( self . to_physical_idx ( len) , value) }
1925
1969
}
1926
1970
1927
1971
#[ inline]
@@ -2007,7 +2051,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
2007
2051
///
2008
2052
/// # Panics
2009
2053
///
2010
- /// Panics if `index` is strictly greater than deque's length
2054
+ /// Panics if `index` is strictly greater than the deque's length.
2011
2055
///
2012
2056
/// # Examples
2013
2057
///
@@ -2029,7 +2073,38 @@ impl<T, A: Allocator> VecDeque<T, A> {
2029
2073
#[ stable( feature = "deque_extras_15" , since = "1.5.0" ) ]
2030
2074
#[ track_caller]
2031
2075
pub fn insert ( & mut self , index : usize , value : T ) {
2032
- assert ! ( index <= self . len( ) , "index out of bounds" ) ;
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,
2081
+ /// and 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 {
2105
+ if core:: intrinsics:: unlikely ( index > self . len ) {
2106
+ panic ! ( "insertion index (is {index}) should be <= len (is {})" , self . len( ) )
2107
+ } ;
2033
2108
if self . is_full ( ) {
2034
2109
self . grow ( ) ;
2035
2110
}
@@ -2042,16 +2117,16 @@ impl<T, A: Allocator> VecDeque<T, A> {
2042
2117
unsafe {
2043
2118
// see `remove()` for explanation why this wrap_copy() call is safe.
2044
2119
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) ;
2046
2120
self . len += 1 ;
2121
+ self . buffer_write ( self . to_physical_idx ( index) , value)
2047
2122
}
2048
2123
} else {
2049
2124
let old_head = self . head ;
2050
2125
self . head = self . wrap_sub ( self . head , 1 ) ;
2051
2126
unsafe {
2052
2127
self . wrap_copy ( old_head, self . head , index) ;
2053
- self . buffer_write ( self . to_physical_idx ( index) , value) ;
2054
2128
self . len += 1 ;
2129
+ self . buffer_write ( self . to_physical_idx ( index) , value)
2055
2130
}
2056
2131
}
2057
2132
}
0 commit comments