1- #[ cfg( not( test) ) ]
2- use core:: iter:: Rev ;
3- use core:: iter:: TrustedLen ;
1+ use core:: iter:: { Copied , Rev , TrustedLen } ;
42use core:: slice;
53
64use super :: VecDeque ;
@@ -158,9 +156,9 @@ where
158156impl < T , A : Allocator > SpecExtendFront < T , vec:: IntoIter < T > > for VecDeque < T , A > {
159157 #[ track_caller]
160158 fn spec_extend_front ( & mut self , mut iterator : vec:: IntoIter < T > ) {
161- let slice = iterator. as_mut_slice ( ) ;
162- slice. reverse ( ) ;
163- unsafe { prepend ( self , slice) } ;
159+ let slice = iterator. as_slice ( ) ;
160+ // SAFETY: elements in the slice are forgotten after this call
161+ unsafe { prepend_reversed ( self , slice) } ;
164162 iterator. forget_remaining_elements ( ) ;
165163 }
166164}
@@ -170,36 +168,40 @@ impl<T, A: Allocator> SpecExtendFront<T, Rev<vec::IntoIter<T>>> for VecDeque<T,
170168 #[ track_caller]
171169 fn spec_extend_front ( & mut self , iterator : Rev < vec:: IntoIter < T > > ) {
172170 let mut iterator = iterator. into_inner ( ) ;
173- unsafe { prepend ( self , iterator. as_slice ( ) ) } ;
171+ let slice = iterator. as_slice ( ) ;
172+ // SAFETY: elements in the slice are forgotten after this call
173+ unsafe { prepend ( self , slice) } ;
174174 iterator. forget_remaining_elements ( ) ;
175175 }
176176}
177177
178- // impl<T, A: Allocator> SpecExtendFront<T, Copied<slice::Iter<'_, T>>> for VecDeque<T, A>
179- // where
180- // T: Copy,
181- // {
182- // #[track_caller]
183- // fn spec_extend_front(&mut self, _iter: Copied<slice::Iter<'_, T>>) {
184- // // unsafe { prepend(self, slice) };
185- // // reverse in place?
186- // }
187- // }
188-
189- // impl<T, A: Allocator> SpecExtendFront<T, Rev<Copied<slice::Iter<'_, T>>>> for VecDeque<T, A>
190- // where
191- // T: Copy,
192- // {
193- // #[track_caller]
194- // fn spec_extend_front(&mut self, iter: Rev<Copied<slice::Iter<'_, T>>>) {
195- // unsafe { prepend(self, iter.into_inner().it.as_slice()) };
196- // }
197- // }
178+ impl < ' a , T , A : Allocator > SpecExtendFront < T , Copied < slice:: Iter < ' a , T > > > for VecDeque < T , A >
179+ where
180+ Copied < slice:: Iter < ' a , T > > : Iterator < Item = T > ,
181+ {
182+ #[ track_caller]
183+ fn spec_extend_front ( & mut self , iter : Copied < slice:: Iter < ' a , T > > ) {
184+ let slice = iter. into_inner ( ) . as_slice ( ) ;
185+ // SAFETY: T is Copy because Copied<slice::Iter<'a, T>> is Iterator
186+ unsafe { prepend_reversed ( self , slice) } ;
187+ }
188+ }
189+
190+ impl < ' a , T , A : Allocator > SpecExtendFront < T , Rev < Copied < slice:: Iter < ' a , T > > > > for VecDeque < T , A >
191+ where
192+ Rev < Copied < slice:: Iter < ' a , T > > > : Iterator < Item = T > ,
193+ {
194+ #[ track_caller]
195+ fn spec_extend_front ( & mut self , iter : Rev < Copied < slice:: Iter < ' a , T > > > ) {
196+ let slice = iter. into_inner ( ) . into_inner ( ) . as_slice ( ) ;
197+ // SAFETY: T is Copy because Rev<Copied<slice::Iter<'a, T>>> is Iterator
198+ unsafe { prepend ( self , slice) } ;
199+ }
200+ }
198201
199202/// # Safety
200203///
201- /// `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`.
202- #[ cfg( not( test) ) ]
204+ /// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`.
203205unsafe fn prepend < T , A : Allocator > ( deque : & mut VecDeque < T , A > , slice : & [ T ] ) {
204206 deque. reserve ( slice. len ( ) ) ;
205207
@@ -209,3 +211,16 @@ unsafe fn prepend<T, A: Allocator>(deque: &mut VecDeque<T, A>, slice: &[T]) {
209211 deque. len += slice. len ( ) ;
210212 }
211213}
214+
215+ /// # Safety
216+ ///
217+ /// Elements of `slice` will be copied into the deque, make sure to forget the items if `T` is not `Copy`.
218+ unsafe fn prepend_reversed < T , A : Allocator > ( deque : & mut VecDeque < T , A > , slice : & [ T ] ) {
219+ deque. reserve ( slice. len ( ) ) ;
220+
221+ unsafe {
222+ deque. head = deque. wrap_sub ( deque. head , slice. len ( ) ) ;
223+ deque. copy_slice_reversed ( deque. head , slice) ;
224+ deque. len += slice. len ( ) ;
225+ }
226+ }
0 commit comments