1- use core:: fmt;
21use core:: iter:: { FusedIterator , TrustedLen } ;
2+ use core:: { array, fmt, mem:: MaybeUninit , ops:: Try , ptr} ;
33
44use crate :: alloc:: { Allocator , Global } ;
55
@@ -52,6 +52,126 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
5252 let len = self . inner . len ( ) ;
5353 ( len, Some ( len) )
5454 }
55+
56+ #[ inline]
57+ fn advance_by ( & mut self , n : usize ) -> Result < ( ) , usize > {
58+ if self . inner . len < n {
59+ let len = self . inner . len ;
60+ self . inner . clear ( ) ;
61+ Err ( len)
62+ } else {
63+ self . inner . drain ( ..n) ;
64+ Ok ( ( ) )
65+ }
66+ }
67+
68+ #[ inline]
69+ fn count ( self ) -> usize {
70+ self . inner . len
71+ }
72+
73+ fn try_fold < B , F , R > ( & mut self , mut init : B , mut f : F ) -> R
74+ where
75+ F : FnMut ( B , Self :: Item ) -> R ,
76+ R : Try < Output = B > ,
77+ {
78+ struct Guard < ' a , T , A : Allocator > {
79+ deque : & ' a mut VecDeque < T , A > ,
80+ // `consumed <= deque.len` always holds.
81+ consumed : usize ,
82+ }
83+
84+ impl < ' a , T , A : Allocator > Drop for Guard < ' a , T , A > {
85+ fn drop ( & mut self ) {
86+ self . deque . len -= self . consumed ;
87+ self . deque . head = self . deque . to_physical_idx ( self . consumed ) ;
88+ }
89+ }
90+
91+ let mut guard = Guard { deque : & mut self . inner , consumed : 0 } ;
92+
93+ let ( head, tail) = guard. deque . as_slices ( ) ;
94+
95+ init = head
96+ . iter ( )
97+ . map ( |elem| {
98+ guard. consumed += 1 ;
99+ // SAFETY: Because we incremented `guard.consumed`, the
100+ // deque effectively forgot the element, so we can take
101+ // ownership
102+ unsafe { ptr:: read ( elem) }
103+ } )
104+ . try_fold ( init, & mut f) ?;
105+
106+ tail. iter ( )
107+ . map ( |elem| {
108+ guard. consumed += 1 ;
109+ // SAFETY: Same as above.
110+ unsafe { ptr:: read ( elem) }
111+ } )
112+ . try_fold ( init, & mut f)
113+ }
114+
115+ #[ inline]
116+ fn fold < B , F > ( mut self , init : B , mut f : F ) -> B
117+ where
118+ F : FnMut ( B , Self :: Item ) -> B ,
119+ {
120+ match self . try_fold ( init, |b, item| Ok :: < B , !> ( f ( b, item) ) ) {
121+ Ok ( b) => b,
122+ Err ( e) => match e { } ,
123+ }
124+ }
125+
126+ #[ inline]
127+ fn last ( mut self ) -> Option < Self :: Item > {
128+ self . inner . pop_back ( )
129+ }
130+
131+ fn next_chunk < const N : usize > (
132+ & mut self ,
133+ ) -> Result < [ Self :: Item ; N ] , array:: IntoIter < Self :: Item , N > > {
134+ let mut raw_arr = MaybeUninit :: uninit_array ( ) ;
135+ let raw_arr_ptr = raw_arr. as_mut_ptr ( ) . cast ( ) ;
136+ let ( head, tail) = self . inner . as_slices ( ) ;
137+
138+ if head. len ( ) >= N {
139+ // SAFETY: By manually adjusting the head and length of the deque, we effectively
140+ // make it forget the first `N` elements, so taking ownership of them is safe.
141+ unsafe { ptr:: copy_nonoverlapping ( head. as_ptr ( ) , raw_arr_ptr, N ) } ;
142+ self . inner . head = self . inner . to_physical_idx ( N ) ;
143+ self . inner . len -= N ;
144+ // SAFETY: We initialized the entire array with items from `head`
145+ return Ok ( unsafe { raw_arr. transpose ( ) . assume_init ( ) } ) ;
146+ }
147+
148+ // SAFETY: Same argument as above.
149+ unsafe { ptr:: copy_nonoverlapping ( head. as_ptr ( ) , raw_arr_ptr, head. len ( ) ) } ;
150+ let remaining = N - head. len ( ) ;
151+
152+ if tail. len ( ) >= remaining {
153+ // SAFETY: Same argument as above.
154+ unsafe {
155+ ptr:: copy_nonoverlapping ( tail. as_ptr ( ) , raw_arr_ptr. add ( head. len ( ) ) , remaining)
156+ } ;
157+ self . inner . head = self . inner . to_physical_idx ( N ) ;
158+ self . inner . len -= N ;
159+ // SAFETY: We initialized the entire array with items from `head` and `tail`
160+ Ok ( unsafe { raw_arr. transpose ( ) . assume_init ( ) } )
161+ } else {
162+ // SAFETY: Same argument as above.
163+ unsafe {
164+ ptr:: copy_nonoverlapping ( tail. as_ptr ( ) , raw_arr_ptr. add ( head. len ( ) ) , tail. len ( ) )
165+ } ;
166+ let init = head. len ( ) + tail. len ( ) ;
167+ // We completely drained all the deques elements.
168+ self . inner . head = 0 ;
169+ self . inner . len = 0 ;
170+ // SAFETY: We copied all elements from both slices to the beginning of the array, so
171+ // the given range is initialized.
172+ Err ( unsafe { array:: IntoIter :: new_unchecked ( raw_arr, 0 ..init) } )
173+ }
174+ }
55175}
56176
57177#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -60,10 +180,73 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
60180 fn next_back ( & mut self ) -> Option < T > {
61181 self . inner . pop_back ( )
62182 }
183+
184+ #[ inline]
185+ fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , usize > {
186+ let len = self . inner . len ;
187+ if len >= n {
188+ self . inner . truncate ( len - n) ;
189+ Ok ( ( ) )
190+ } else {
191+ self . inner . clear ( ) ;
192+ Err ( len)
193+ }
194+ }
195+
196+ fn try_rfold < B , F , R > ( & mut self , mut init : B , mut f : F ) -> R
197+ where
198+ F : FnMut ( B , Self :: Item ) -> R ,
199+ R : Try < Output = B > ,
200+ {
201+ struct Guard < ' a , T , A : Allocator > {
202+ deque : & ' a mut VecDeque < T , A > ,
203+ // `consumed <= deque.len` always holds.
204+ consumed : usize ,
205+ }
206+
207+ impl < ' a , T , A : Allocator > Drop for Guard < ' a , T , A > {
208+ fn drop ( & mut self ) {
209+ self . deque . len -= self . consumed ;
210+ }
211+ }
212+
213+ let mut guard = Guard { deque : & mut self . inner , consumed : 0 } ;
214+
215+ let ( head, tail) = guard. deque . as_slices ( ) ;
216+
217+ init = tail
218+ . iter ( )
219+ . map ( |elem| {
220+ guard. consumed += 1 ;
221+ // SAFETY: See `try_fold`'s safety comment.
222+ unsafe { ptr:: read ( elem) }
223+ } )
224+ . try_rfold ( init, & mut f) ?;
225+
226+ head. iter ( )
227+ . map ( |elem| {
228+ guard. consumed += 1 ;
229+ // SAFETY: Same as above.
230+ unsafe { ptr:: read ( elem) }
231+ } )
232+ . try_rfold ( init, & mut f)
233+ }
234+
235+ #[ inline]
236+ fn rfold < B , F > ( mut self , init : B , mut f : F ) -> B
237+ where
238+ F : FnMut ( B , Self :: Item ) -> B ,
239+ {
240+ match self . try_rfold ( init, |b, item| Ok :: < B , !> ( f ( b, item) ) ) {
241+ Ok ( b) => b,
242+ Err ( e) => match e { } ,
243+ }
244+ }
63245}
64246
65247#[ stable( feature = "rust1" , since = "1.0.0" ) ]
66248impl < T , A : Allocator > ExactSizeIterator for IntoIter < T , A > {
249+ #[ inline]
67250 fn is_empty ( & self ) -> bool {
68251 self . inner . is_empty ( )
69252 }
0 commit comments