@@ -161,22 +161,41 @@ where
161
161
}
162
162
}
163
163
164
+ /// Creates an array one element at a time using a mutable iterator
165
+ /// you can write to with `ptr::write`.
166
+ ///
167
+ /// Incremenent the position while iterating to mark off created elements,
168
+ /// which will be dropped if `into_inner` is not called.
164
169
#[ doc( hidden) ]
165
170
pub struct ArrayBuilder < T , N : ArrayLength < T > > {
166
- pub array : ManuallyDrop < GenericArray < T , N > > ,
167
- pub position : usize ,
171
+ array : ManuallyDrop < GenericArray < T , N > > ,
172
+ position : usize ,
168
173
}
169
174
170
175
impl < T , N : ArrayLength < T > > ArrayBuilder < T , N > {
171
176
#[ doc( hidden) ]
177
+ #[ inline]
172
178
pub unsafe fn new ( ) -> ArrayBuilder < T , N > {
173
179
ArrayBuilder {
174
180
array : ManuallyDrop :: new ( mem:: uninitialized ( ) ) ,
175
181
position : 0 ,
176
182
}
177
183
}
178
184
185
+ /// Creates a mutable iterator for writing to the array using `ptr::write`.
186
+ ///
187
+ /// Increment the position value given as a mutable reference as you iterate
188
+ /// to mark how many elements have been created.
189
+ #[ doc( hidden) ]
190
+ #[ inline]
191
+ pub unsafe fn iter_position ( & mut self ) -> ( slice:: IterMut < T > , & mut usize ) {
192
+ ( self . array . iter_mut ( ) , & mut self . position )
193
+ }
194
+
195
+ /// When done writing (assuming all elements have been written to),
196
+ /// get the inner array.
179
197
#[ doc( hidden) ]
198
+ #[ inline]
180
199
pub unsafe fn into_inner ( self ) -> GenericArray < T , N > {
181
200
let array = ptr:: read ( & self . array ) ;
182
201
@@ -188,35 +207,50 @@ impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
188
207
189
208
impl < T , N : ArrayLength < T > > Drop for ArrayBuilder < T , N > {
190
209
fn drop ( & mut self ) {
191
- for value in self . array . iter_mut ( ) . take ( self . position ) {
210
+ for value in & mut self . array [ .. self . position ] {
192
211
unsafe {
193
212
ptr:: drop_in_place ( value) ;
194
213
}
195
214
}
196
215
}
197
216
}
198
217
218
+ /// Consumes an array.
219
+ ///
220
+ /// Increment the position while iterating and any leftover elements
221
+ /// will be dropped if position does not go to N
199
222
#[ doc( hidden) ]
200
223
pub struct ArrayConsumer < T , N : ArrayLength < T > > {
201
- pub array : ManuallyDrop < GenericArray < T , N > > ,
202
- pub position : usize ,
224
+ array : ManuallyDrop < GenericArray < T , N > > ,
225
+ position : usize ,
203
226
}
204
227
205
228
impl < T , N : ArrayLength < T > > ArrayConsumer < T , N > {
206
229
#[ doc( hidden) ]
230
+ #[ inline]
207
231
pub unsafe fn new ( array : GenericArray < T , N > ) -> ArrayConsumer < T , N > {
208
232
ArrayConsumer {
209
233
array : ManuallyDrop :: new ( array) ,
210
234
position : 0 ,
211
235
}
212
236
}
237
+
238
+ /// Creates an iterator and mutable reference to the internal position
239
+ /// to keep track of consumed elements.
240
+ ///
241
+ /// Increment the position as you iterate to mark off consumed elements
242
+ #[ doc( hidden) ]
243
+ #[ inline]
244
+ pub unsafe fn iter_position ( & mut self ) -> ( slice:: Iter < T > , & mut usize ) {
245
+ ( self . array . iter ( ) , & mut self . position )
246
+ }
213
247
}
214
248
215
249
impl < T , N : ArrayLength < T > > Drop for ArrayConsumer < T , N > {
216
250
fn drop ( & mut self ) {
217
- for i in self . position ..N :: to_usize ( ) {
251
+ for value in & mut self . array [ self . position ..N :: to_usize ( ) ] {
218
252
unsafe {
219
- ptr:: drop_in_place ( self . array . get_unchecked_mut ( i ) ) ;
253
+ ptr:: drop_in_place ( value ) ;
220
254
}
221
255
}
222
256
}
@@ -254,21 +288,25 @@ where
254
288
where
255
289
I : IntoIterator < Item = T > ,
256
290
{
257
- let mut destination = unsafe { ArrayBuilder :: new ( ) } ;
291
+ unsafe {
292
+ let mut destination = ArrayBuilder :: new ( ) ;
258
293
259
- for ( src, dst) in iter. into_iter ( ) . zip ( destination. array . iter_mut ( ) ) {
260
- unsafe {
261
- ptr:: write ( dst, src) ;
294
+ {
295
+ let ( destination_iter, position) = destination. iter_position ( ) ;
296
+
297
+ for ( src, dst) in iter. into_iter ( ) . zip ( destination_iter) {
298
+ ptr:: write ( dst, src) ;
299
+
300
+ * position += 1 ;
301
+ }
262
302
}
263
303
264
- destination. position += 1 ;
265
- }
304
+ if destination. position < N :: to_usize ( ) {
305
+ from_iter_length_fail ( destination. position , N :: to_usize ( ) ) ;
306
+ }
266
307
267
- if destination. position < N :: to_usize ( ) {
268
- from_iter_length_fail ( destination. position , N :: to_usize ( ) ) ;
308
+ destination. into_inner ( )
269
309
}
270
-
271
- unsafe { destination. into_inner ( ) }
272
310
}
273
311
}
274
312
@@ -293,17 +331,21 @@ where
293
331
where
294
332
F : FnMut ( usize ) -> T ,
295
333
{
296
- let mut destination = unsafe { ArrayBuilder :: new ( ) } ;
334
+ unsafe {
335
+ let mut destination = ArrayBuilder :: new ( ) ;
297
336
298
- for ( i, dst) in destination. array . iter_mut ( ) . enumerate ( ) {
299
- unsafe {
300
- ptr:: write ( dst, f ( i) ) ;
337
+ {
338
+ let ( destination_iter, position) = destination. iter_position ( ) ;
339
+
340
+ for ( i, dst) in destination_iter. enumerate ( ) {
341
+ ptr:: write ( dst, f ( i) ) ;
342
+
343
+ * position += 1 ;
344
+ }
301
345
}
302
346
303
- destination. position += 1 ;
347
+ destination. into_inner ( )
304
348
}
305
-
306
- unsafe { destination. into_inner ( ) }
307
349
}
308
350
309
351
#[ doc( hidden) ]
@@ -319,27 +361,23 @@ where
319
361
Self :: Length : ArrayLength < B > + ArrayLength < U > ,
320
362
F : FnMut ( B , Self :: Item ) -> U ,
321
363
{
322
- let mut left = unsafe { ArrayConsumer :: new ( lhs) } ;
323
- let mut right = unsafe { ArrayConsumer :: new ( self ) } ;
324
-
325
- let ArrayConsumer {
326
- array : ref left_array,
327
- position : ref mut left_position,
328
- } = left;
329
- let ArrayConsumer {
330
- array : ref right_array,
331
- position : ref mut right_position,
332
- } = right;
333
-
334
- FromIterator :: from_iter ( left_array. iter ( ) . zip ( right_array. iter ( ) ) . map ( |( l, r) | {
335
- let left_value = unsafe { ptr:: read ( l) } ;
336
- let right_value = unsafe { ptr:: read ( r) } ;
337
-
338
- * left_position += 1 ;
339
- * right_position += 1 ;
340
-
341
- f ( left_value, right_value)
342
- } ) )
364
+ unsafe {
365
+ let mut left = ArrayConsumer :: new ( lhs) ;
366
+ let mut right = ArrayConsumer :: new ( self ) ;
367
+
368
+ let ( left_array_iter, left_position) = left. iter_position ( ) ;
369
+ let ( right_array_iter, right_position) = right. iter_position ( ) ;
370
+
371
+ FromIterator :: from_iter ( left_array_iter. zip ( right_array_iter) . map ( |( l, r) | {
372
+ let left_value = ptr:: read ( l) ;
373
+ let right_value = ptr:: read ( r) ;
374
+
375
+ * left_position += 1 ;
376
+ * right_position += 1 ;
377
+
378
+ f ( left_value, right_value)
379
+ } ) )
380
+ }
343
381
}
344
382
345
383
#[ doc( hidden) ]
@@ -350,24 +388,23 @@ where
350
388
Self :: Length : ArrayLength < B > + ArrayLength < U > ,
351
389
F : FnMut ( Lhs :: Item , Self :: Item ) -> U ,
352
390
{
353
- let mut right = unsafe { ArrayConsumer :: new ( self ) } ;
391
+ unsafe {
392
+ let mut right = ArrayConsumer :: new ( self ) ;
354
393
355
- let ArrayConsumer {
356
- array : ref right_array,
357
- position : ref mut right_position,
358
- } = right;
394
+ let ( right_array_iter, right_position) = right. iter_position ( ) ;
359
395
360
- FromIterator :: from_iter (
361
- lhs. into_iter ( )
362
- . zip ( right_array . iter ( ) )
363
- . map ( |( left_value, r) | {
364
- let right_value = unsafe { ptr:: read ( r) } ;
396
+ FromIterator :: from_iter (
397
+ lhs. into_iter ( )
398
+ . zip ( right_array_iter )
399
+ . map ( |( left_value, r) | {
400
+ let right_value = ptr:: read ( r) ;
365
401
366
- * right_position += 1 ;
402
+ * right_position += 1 ;
367
403
368
- f ( left_value, right_value)
369
- } ) ,
370
- )
404
+ f ( left_value, right_value)
405
+ } ) ,
406
+ )
407
+ }
371
408
}
372
409
}
373
410
@@ -390,20 +427,19 @@ where
390
427
Self : MappedGenericSequence < T , U > ,
391
428
F : FnMut ( T ) -> U ,
392
429
{
393
- let mut source = unsafe { ArrayConsumer :: new ( self ) } ;
430
+ unsafe {
431
+ let mut source = ArrayConsumer :: new ( self ) ;
394
432
395
- let ArrayConsumer {
396
- ref array,
397
- ref mut position,
398
- } = source;
433
+ let ( array_iter, position) = source. iter_position ( ) ;
399
434
400
- FromIterator :: from_iter ( array . iter ( ) . map ( |src| {
401
- let value = unsafe { ptr:: read ( src) } ;
435
+ FromIterator :: from_iter ( array_iter . map ( |src| {
436
+ let value = ptr:: read ( src) ;
402
437
403
- * position += 1 ;
438
+ * position += 1 ;
404
439
405
- f ( value)
406
- } ) )
440
+ f ( value)
441
+ } ) )
442
+ }
407
443
}
408
444
409
445
#[ inline]
@@ -422,20 +458,19 @@ where
422
458
where
423
459
F : FnMut ( U , T ) -> U ,
424
460
{
425
- let mut source = unsafe { ArrayConsumer :: new ( self ) } ;
461
+ unsafe {
462
+ let mut source = ArrayConsumer :: new ( self ) ;
426
463
427
- let ArrayConsumer {
428
- ref array,
429
- ref mut position,
430
- } = source;
464
+ let ( array_iter, position) = source. iter_position ( ) ;
431
465
432
- array . iter ( ) . fold ( init, |acc, src| {
433
- let value = unsafe { ptr:: read ( src) } ;
466
+ array_iter . fold ( init, |acc, src| {
467
+ let value = ptr:: read ( src) ;
434
468
435
- * position += 1 ;
469
+ * position += 1 ;
436
470
437
- f ( acc, value)
438
- } )
471
+ f ( acc, value)
472
+ } )
473
+ }
439
474
}
440
475
}
441
476
@@ -525,17 +560,21 @@ where
525
560
let iter = iter. into_iter ( ) ;
526
561
527
562
if iter. len ( ) == N :: to_usize ( ) {
528
- let mut destination = unsafe { ArrayBuilder :: new ( ) } ;
563
+ unsafe {
564
+ let mut destination = ArrayBuilder :: new ( ) ;
529
565
530
- for ( dst, src) in destination. array . iter_mut ( ) . zip ( iter. into_iter ( ) ) {
531
- unsafe {
532
- ptr:: write ( dst, src) ;
566
+ {
567
+ let ( destination_iter, position) = destination. iter_position ( ) ;
568
+
569
+ for ( dst, src) in destination_iter. zip ( iter. into_iter ( ) ) {
570
+ ptr:: write ( dst, src) ;
571
+
572
+ * position += 1 ;
573
+ }
533
574
}
534
575
535
- destination. position += 1 ;
576
+ Some ( destination. into_inner ( ) )
536
577
}
537
-
538
- Some ( unsafe { destination. into_inner ( ) } )
539
578
} else {
540
579
None
541
580
}
0 commit comments