@@ -47,7 +47,7 @@ pub use self::iter::Iter;
47
47
48
48
mod iter;
49
49
50
- use self :: spec_extend:: SpecExtend ;
50
+ use self :: spec_extend:: { SpecExtend , SpecExtendFront } ;
51
51
52
52
mod spec_extend;
53
53
@@ -174,6 +174,21 @@ impl<T, A: Allocator> VecDeque<T, A> {
174
174
self . len += 1 ;
175
175
}
176
176
177
+ /// Prepends an element to the buffer.
178
+ ///
179
+ /// # Safety
180
+ ///
181
+ /// May only be called if `deque.len() < deque.capacity()`
182
+ #[ inline]
183
+ unsafe fn push_front_unchecked ( & mut self , element : T ) {
184
+ self . head = self . wrap_sub ( self . head , 1 ) ;
185
+ // SAFETY: Because of the precondition, it's guaranteed that there is space
186
+ // in the logical array before the first element (where self.head is now).
187
+ unsafe { self . buffer_write ( self . head , element) } ;
188
+ // This can't overflow because `deque.len() < deque.capacity() <= usize::MAX`.
189
+ self . len += 1 ;
190
+ }
191
+
177
192
/// Moves an element out of the buffer
178
193
#[ inline]
179
194
unsafe fn buffer_read ( & mut self , off : usize ) -> T {
@@ -1956,6 +1971,73 @@ impl<T, A: Allocator> VecDeque<T, A> {
1956
1971
unsafe { self . buffer_write ( self . to_physical_idx ( len) , value) }
1957
1972
}
1958
1973
1974
+ /// Prepends all contents of the iterator to the front of the deque.
1975
+ /// The order of the contents is preserved.
1976
+ ///
1977
+ /// To get behavior like [`append`][VecDeque::append] where elements are moved
1978
+ /// from the other collection to this one, use `self.prepend(other.drain(..))`.
1979
+ ///
1980
+ /// # Examples
1981
+ ///
1982
+ /// ```
1983
+ /// #![feature(deque_extend_front)]
1984
+ /// use std::collections::VecDeque;
1985
+ ///
1986
+ /// let mut deque = VecDeque::from([4, 5, 6]);
1987
+ /// deque.prepend([1, 2, 3]);
1988
+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
1989
+ /// ```
1990
+ ///
1991
+ /// Move values between collections like [`append`][VecDeque::append] does but prepend to the front:
1992
+ ///
1993
+ /// ```
1994
+ /// #![feature(deque_extend_front)]
1995
+ /// use std::collections::VecDeque;
1996
+ ///
1997
+ /// let mut deque1 = VecDeque::from([4, 5, 6]);
1998
+ /// let mut deque2 = VecDeque::from([1, 2, 3]);
1999
+ /// deque1.prepend(deque2.drain(..));
2000
+ /// assert_eq!(deque1, [1, 2, 3, 4, 5, 6]);
2001
+ /// assert!(deque2.is_empty());
2002
+ /// ```
2003
+ #[ unstable( feature = "deque_extend_front" , issue = "146975" ) ]
2004
+ #[ track_caller]
2005
+ pub fn prepend < I : IntoIterator < Item = T , IntoIter : DoubleEndedIterator > > ( & mut self , other : I ) {
2006
+ self . extend_front ( other. into_iter ( ) . rev ( ) )
2007
+ }
2008
+
2009
+ /// Prepends all contents of the iterator to the front of the deque,
2010
+ /// as if [`push_front`][VecDeque::push_front] was called repeatedly with
2011
+ /// the values yielded by the iterator.
2012
+ ///
2013
+ /// # Examples
2014
+ ///
2015
+ /// ```
2016
+ /// #![feature(deque_extend_front)]
2017
+ /// use std::collections::VecDeque;
2018
+ ///
2019
+ /// let mut deque = VecDeque::from([4, 5, 6]);
2020
+ /// deque.extend_front([3, 2, 1]);
2021
+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
2022
+ /// ```
2023
+ ///
2024
+ /// This behaves like [`push_front`][VecDeque::push_front] was called repeatedly:
2025
+ ///
2026
+ /// ```
2027
+ /// use std::collections::VecDeque;
2028
+ ///
2029
+ /// let mut deque = VecDeque::from([4, 5, 6]);
2030
+ /// for v in [3, 2, 1] {
2031
+ /// deque.push_front(v);
2032
+ /// }
2033
+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
2034
+ /// ```
2035
+ #[ unstable( feature = "deque_extend_front" , issue = "146975" ) ]
2036
+ #[ track_caller]
2037
+ pub fn extend_front < I : IntoIterator < Item = T > > ( & mut self , iter : I ) {
2038
+ <Self as SpecExtendFront < T , I :: IntoIter > >:: spec_extend_front ( self , iter. into_iter ( ) ) ;
2039
+ }
2040
+
1959
2041
#[ inline]
1960
2042
fn is_contiguous ( & self ) -> bool {
1961
2043
// Do the calculation like this to avoid overflowing if len + head > usize::MAX
0 commit comments