@@ -52,7 +52,7 @@ pub use self::iter::Iter;
5252
5353mod iter;
5454
55- use self :: spec_extend:: SpecExtend ;
55+ use self :: spec_extend:: { SpecExtend , SpecExtendFront } ;
5656
5757mod spec_extend;
5858
@@ -179,6 +179,21 @@ impl<T, A: Allocator> VecDeque<T, A> {
179179 self . len += 1 ;
180180 }
181181
182+ /// Prepends an element to the buffer.
183+ ///
184+ /// # Safety
185+ ///
186+ /// May only be called if `deque.len() < deque.capacity()`
187+ #[ inline]
188+ unsafe fn push_front_unchecked ( & mut self , element : T ) {
189+ self . head = self . wrap_sub ( self . head , 1 ) ;
190+ // SAFETY: Because of the precondition, it's guaranteed that there is space
191+ // in the logical array before the first element (where self.head is now).
192+ unsafe { self . buffer_write ( self . head , element) } ;
193+ // This can't overflow because `deque.len() < deque.capacity() <= usize::MAX`.
194+ self . len += 1 ;
195+ }
196+
182197 /// Moves an element out of the buffer
183198 #[ inline]
184199 unsafe fn buffer_read ( & mut self , off : usize ) -> T {
@@ -2122,6 +2137,73 @@ impl<T, A: Allocator> VecDeque<T, A> {
21222137 unsafe { self . buffer_write ( self . to_physical_idx ( len) , value) }
21232138 }
21242139
2140+ /// Prepends all contents of the iterator to the front of the deque.
2141+ /// The order of the contents is preserved.
2142+ ///
2143+ /// To get behavior like [`append`][VecDeque::append] where elements are moved
2144+ /// from the other collection to this one, use `self.prepend(other.drain(..))`.
2145+ ///
2146+ /// # Examples
2147+ ///
2148+ /// ```
2149+ /// #![feature(deque_extend_front)]
2150+ /// use std::collections::VecDeque;
2151+ ///
2152+ /// let mut deque = VecDeque::from([4, 5, 6]);
2153+ /// deque.prepend([1, 2, 3]);
2154+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
2155+ /// ```
2156+ ///
2157+ /// Move values between collections like [`append`][VecDeque::append] does but prepend to the front:
2158+ ///
2159+ /// ```
2160+ /// #![feature(deque_extend_front)]
2161+ /// use std::collections::VecDeque;
2162+ ///
2163+ /// let mut deque1 = VecDeque::from([4, 5, 6]);
2164+ /// let mut deque2 = VecDeque::from([1, 2, 3]);
2165+ /// deque1.prepend(deque2.drain(..));
2166+ /// assert_eq!(deque1, [1, 2, 3, 4, 5, 6]);
2167+ /// assert!(deque2.is_empty());
2168+ /// ```
2169+ #[ unstable( feature = "deque_extend_front" , issue = "146975" ) ]
2170+ #[ track_caller]
2171+ pub fn prepend < I : IntoIterator < Item = T , IntoIter : DoubleEndedIterator > > ( & mut self , other : I ) {
2172+ self . extend_front ( other. into_iter ( ) . rev ( ) )
2173+ }
2174+
2175+ /// Prepends all contents of the iterator to the front of the deque,
2176+ /// as if [`push_front`][VecDeque::push_front] was called repeatedly with
2177+ /// the values yielded by the iterator.
2178+ ///
2179+ /// # Examples
2180+ ///
2181+ /// ```
2182+ /// #![feature(deque_extend_front)]
2183+ /// use std::collections::VecDeque;
2184+ ///
2185+ /// let mut deque = VecDeque::from([4, 5, 6]);
2186+ /// deque.extend_front([3, 2, 1]);
2187+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
2188+ /// ```
2189+ ///
2190+ /// This behaves like [`push_front`][VecDeque::push_front] was called repeatedly:
2191+ ///
2192+ /// ```
2193+ /// use std::collections::VecDeque;
2194+ ///
2195+ /// let mut deque = VecDeque::from([4, 5, 6]);
2196+ /// for v in [3, 2, 1] {
2197+ /// deque.push_front(v);
2198+ /// }
2199+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
2200+ /// ```
2201+ #[ unstable( feature = "deque_extend_front" , issue = "146975" ) ]
2202+ #[ track_caller]
2203+ pub fn extend_front < I : IntoIterator < Item = T > > ( & mut self , iter : I ) {
2204+ <Self as SpecExtendFront < T , I :: IntoIter > >:: spec_extend_front ( self , iter. into_iter ( ) ) ;
2205+ }
2206+
21252207 #[ inline]
21262208 fn is_contiguous ( & self ) -> bool {
21272209 // Do the calculation like this to avoid overflowing if len + head > usize::MAX
0 commit comments