@@ -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 {
@@ -505,6 +520,35 @@ impl<T, A: Allocator> VecDeque<T, A> {
505520 }
506521 }
507522
523+ /// Copies all values from `src` to `dst` in reversed order, wrapping around if needed.
524+ /// Assumes capacity is sufficient.
525+ /// Equivalent to calling [`VecDeque::copy_slice`] with a [reversed](https://doc.rust-lang.org/std/primitive.slice.html#method.reverse) slice.
526+ #[ inline]
527+ unsafe fn copy_slice_reversed ( & mut self , dst : usize , src : & [ T ] ) {
528+ /// # Safety
529+ ///
530+ /// See [`ptr::copy_nonoverlapping`].
531+ unsafe fn copy_nonoverlapping_reversed < T > ( src : * const T , dst : * mut T , count : usize ) {
532+ for i in 0 ..count {
533+ unsafe { ptr:: copy_nonoverlapping ( src. add ( count - 1 - i) , dst. add ( i) , 1 ) } ;
534+ }
535+ }
536+
537+ debug_assert ! ( src. len( ) <= self . capacity( ) ) ;
538+ let head_room = self . capacity ( ) - dst;
539+ if src. len ( ) <= head_room {
540+ unsafe {
541+ copy_nonoverlapping_reversed ( src. as_ptr ( ) , self . ptr ( ) . add ( dst) , src. len ( ) ) ;
542+ }
543+ } else {
544+ let ( left, right) = src. split_at ( src. len ( ) - head_room) ;
545+ unsafe {
546+ copy_nonoverlapping_reversed ( right. as_ptr ( ) , self . ptr ( ) . add ( dst) , right. len ( ) ) ;
547+ copy_nonoverlapping_reversed ( left. as_ptr ( ) , self . ptr ( ) , left. len ( ) ) ;
548+ }
549+ }
550+ }
551+
508552 /// Writes all values from `iter` to `dst`.
509553 ///
510554 /// # Safety
@@ -2122,6 +2166,73 @@ impl<T, A: Allocator> VecDeque<T, A> {
21222166 unsafe { self . buffer_write ( self . to_physical_idx ( len) , value) }
21232167 }
21242168
2169+ /// Prepends all contents of the iterator to the front of the deque.
2170+ /// The order of the contents is preserved.
2171+ ///
2172+ /// To get behavior like [`append`][VecDeque::append] where elements are moved
2173+ /// from the other collection to this one, use `self.prepend(other.drain(..))`.
2174+ ///
2175+ /// # Examples
2176+ ///
2177+ /// ```
2178+ /// #![feature(deque_extend_front)]
2179+ /// use std::collections::VecDeque;
2180+ ///
2181+ /// let mut deque = VecDeque::from([4, 5, 6]);
2182+ /// deque.prepend([1, 2, 3]);
2183+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
2184+ /// ```
2185+ ///
2186+ /// Move values between collections like [`append`][VecDeque::append] does but prepend to the front:
2187+ ///
2188+ /// ```
2189+ /// #![feature(deque_extend_front)]
2190+ /// use std::collections::VecDeque;
2191+ ///
2192+ /// let mut deque1 = VecDeque::from([4, 5, 6]);
2193+ /// let mut deque2 = VecDeque::from([1, 2, 3]);
2194+ /// deque1.prepend(deque2.drain(..));
2195+ /// assert_eq!(deque1, [1, 2, 3, 4, 5, 6]);
2196+ /// assert!(deque2.is_empty());
2197+ /// ```
2198+ #[ unstable( feature = "deque_extend_front" , issue = "146975" ) ]
2199+ #[ track_caller]
2200+ pub fn prepend < I : IntoIterator < Item = T , IntoIter : DoubleEndedIterator > > ( & mut self , other : I ) {
2201+ self . extend_front ( other. into_iter ( ) . rev ( ) )
2202+ }
2203+
2204+ /// Prepends all contents of the iterator to the front of the deque,
2205+ /// as if [`push_front`][VecDeque::push_front] was called repeatedly with
2206+ /// the values yielded by the iterator.
2207+ ///
2208+ /// # Examples
2209+ ///
2210+ /// ```
2211+ /// #![feature(deque_extend_front)]
2212+ /// use std::collections::VecDeque;
2213+ ///
2214+ /// let mut deque = VecDeque::from([4, 5, 6]);
2215+ /// deque.extend_front([3, 2, 1]);
2216+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
2217+ /// ```
2218+ ///
2219+ /// This behaves like [`push_front`][VecDeque::push_front] was called repeatedly:
2220+ ///
2221+ /// ```
2222+ /// use std::collections::VecDeque;
2223+ ///
2224+ /// let mut deque = VecDeque::from([4, 5, 6]);
2225+ /// for v in [3, 2, 1] {
2226+ /// deque.push_front(v);
2227+ /// }
2228+ /// assert_eq!(deque, [1, 2, 3, 4, 5, 6]);
2229+ /// ```
2230+ #[ unstable( feature = "deque_extend_front" , issue = "146975" ) ]
2231+ #[ track_caller]
2232+ pub fn extend_front < I : IntoIterator < Item = T > > ( & mut self , iter : I ) {
2233+ <Self as SpecExtendFront < T , I :: IntoIter > >:: spec_extend_front ( self , iter. into_iter ( ) ) ;
2234+ }
2235+
21252236 #[ inline]
21262237 fn is_contiguous ( & self ) -> bool {
21272238 // Do the calculation like this to avoid overflowing if len + head > usize::MAX
0 commit comments