1
- use core:: fmt;
2
1
use core:: iter:: { FusedIterator , TrustedLen } ;
2
+ use core:: { array, fmt, mem:: MaybeUninit , ops:: Try , ptr} ;
3
3
4
4
use crate :: alloc:: { Allocator , Global } ;
5
5
@@ -52,6 +52,126 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
52
52
let len = self . inner . len ( ) ;
53
53
( len, Some ( len) )
54
54
}
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
+ }
55
175
}
56
176
57
177
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -60,10 +180,73 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
60
180
fn next_back ( & mut self ) -> Option < T > {
61
181
self . inner . pop_back ( )
62
182
}
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
+ }
63
245
}
64
246
65
247
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
66
248
impl < T , A : Allocator > ExactSizeIterator for IntoIter < T , A > {
249
+ #[ inline]
67
250
fn is_empty ( & self ) -> bool {
68
251
self . inner . is_empty ( )
69
252
}
0 commit comments