@@ -161,21 +161,43 @@ where
161
161
}
162
162
}
163
163
164
- struct ArrayBuilder < T , N : ArrayLength < T > > {
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.
169
+ #[ doc( hidden) ]
170
+ pub struct ArrayBuilder < T , N : ArrayLength < T > > {
165
171
array : ManuallyDrop < GenericArray < T , N > > ,
166
172
position : usize ,
167
173
}
168
174
169
175
impl < T , N : ArrayLength < T > > ArrayBuilder < T , N > {
170
- fn new ( ) -> ArrayBuilder < T , N > {
176
+ #[ doc( hidden) ]
177
+ #[ inline]
178
+ pub unsafe fn new ( ) -> ArrayBuilder < T , N > {
171
179
ArrayBuilder {
172
- array : ManuallyDrop :: new ( unsafe { mem:: uninitialized ( ) } ) ,
180
+ array : ManuallyDrop :: new ( mem:: uninitialized ( ) ) ,
173
181
position : 0 ,
174
182
}
175
183
}
176
184
177
- fn into_inner ( self ) -> GenericArray < T , N > {
178
- let array = unsafe { ptr:: read ( & self . array ) } ;
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.
197
+ #[ doc( hidden) ]
198
+ #[ inline]
199
+ pub unsafe fn into_inner ( self ) -> GenericArray < T , N > {
200
+ let array = ptr:: read ( & self . array ) ;
179
201
180
202
mem:: forget ( self ) ;
181
203
@@ -185,33 +207,50 @@ impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
185
207
186
208
impl < T , N : ArrayLength < T > > Drop for ArrayBuilder < T , N > {
187
209
fn drop ( & mut self ) {
188
- for value in self . array . iter_mut ( ) . take ( self . position ) {
210
+ for value in & mut self . array [ .. self . position ] {
189
211
unsafe {
190
212
ptr:: drop_in_place ( value) ;
191
213
}
192
214
}
193
215
}
194
216
}
195
217
196
- struct ArrayConsumer < T , N : ArrayLength < T > > {
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
222
+ #[ doc( hidden) ]
223
+ pub struct ArrayConsumer < T , N : ArrayLength < T > > {
197
224
array : ManuallyDrop < GenericArray < T , N > > ,
198
225
position : usize ,
199
226
}
200
227
201
228
impl < T , N : ArrayLength < T > > ArrayConsumer < T , N > {
202
- fn new ( array : GenericArray < T , N > ) -> ArrayConsumer < T , N > {
229
+ #[ doc( hidden) ]
230
+ #[ inline]
231
+ pub unsafe fn new ( array : GenericArray < T , N > ) -> ArrayConsumer < T , N > {
203
232
ArrayConsumer {
204
233
array : ManuallyDrop :: new ( array) ,
205
234
position : 0 ,
206
235
}
207
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
+ }
208
247
}
209
248
210
249
impl < T , N : ArrayLength < T > > Drop for ArrayConsumer < T , N > {
211
250
fn drop ( & mut self ) {
212
- for i in self . position ..N :: to_usize ( ) {
251
+ for value in & mut self . array [ self . position ..N :: to_usize ( ) ] {
213
252
unsafe {
214
- ptr:: drop_in_place ( self . array . get_unchecked_mut ( i ) ) ;
253
+ ptr:: drop_in_place ( value ) ;
215
254
}
216
255
}
217
256
}
@@ -249,21 +288,25 @@ where
249
288
where
250
289
I : IntoIterator < Item = T > ,
251
290
{
252
- let mut destination = ArrayBuilder :: new ( ) ;
291
+ unsafe {
292
+ let mut destination = ArrayBuilder :: new ( ) ;
253
293
254
- for ( src, dst) in iter. into_iter ( ) . zip ( destination. array . iter_mut ( ) ) {
255
- unsafe {
256
- 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
+ }
257
302
}
258
303
259
- destination. position += 1 ;
260
- }
304
+ if destination. position < N :: to_usize ( ) {
305
+ from_iter_length_fail ( destination. position , N :: to_usize ( ) ) ;
306
+ }
261
307
262
- if destination. position < N :: to_usize ( ) {
263
- from_iter_length_fail ( destination. position , N :: to_usize ( ) ) ;
308
+ destination. into_inner ( )
264
309
}
265
-
266
- destination. into_inner ( )
267
310
}
268
311
}
269
312
@@ -288,17 +331,21 @@ where
288
331
where
289
332
F : FnMut ( usize ) -> T ,
290
333
{
291
- let mut destination = ArrayBuilder :: new ( ) ;
334
+ unsafe {
335
+ let mut destination = ArrayBuilder :: new ( ) ;
292
336
293
- for ( i, dst) in destination. array . iter_mut ( ) . enumerate ( ) {
294
- unsafe {
295
- 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
+ }
296
345
}
297
346
298
- destination. position += 1 ;
347
+ destination. into_inner ( )
299
348
}
300
-
301
- destination. into_inner ( )
302
349
}
303
350
304
351
#[ doc( hidden) ]
@@ -314,27 +361,23 @@ where
314
361
Self :: Length : ArrayLength < B > + ArrayLength < U > ,
315
362
F : FnMut ( B , Self :: Item ) -> U ,
316
363
{
317
- let mut left = ArrayConsumer :: new ( lhs) ;
318
- let mut right = ArrayConsumer :: new ( self ) ;
319
-
320
- let ArrayConsumer {
321
- array : ref left_array,
322
- position : ref mut left_position,
323
- } = left;
324
- let ArrayConsumer {
325
- array : ref right_array,
326
- position : ref mut right_position,
327
- } = right;
328
-
329
- FromIterator :: from_iter ( left_array. iter ( ) . zip ( right_array. iter ( ) ) . map ( |( l, r) | {
330
- let left_value = unsafe { ptr:: read ( l) } ;
331
- let right_value = unsafe { ptr:: read ( r) } ;
332
-
333
- * left_position += 1 ;
334
- * right_position += 1 ;
335
-
336
- f ( left_value, right_value)
337
- } ) )
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
+ }
338
381
}
339
382
340
383
#[ doc( hidden) ]
@@ -345,24 +388,23 @@ where
345
388
Self :: Length : ArrayLength < B > + ArrayLength < U > ,
346
389
F : FnMut ( Lhs :: Item , Self :: Item ) -> U ,
347
390
{
348
- let mut right = ArrayConsumer :: new ( self ) ;
391
+ unsafe {
392
+ let mut right = ArrayConsumer :: new ( self ) ;
349
393
350
- let ArrayConsumer {
351
- array : ref right_array,
352
- position : ref mut right_position,
353
- } = right;
394
+ let ( right_array_iter, right_position) = right. iter_position ( ) ;
354
395
355
- FromIterator :: from_iter (
356
- lhs. into_iter ( )
357
- . zip ( right_array . iter ( ) )
358
- . map ( |( left_value, r) | {
359
- 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) ;
360
401
361
- * right_position += 1 ;
402
+ * right_position += 1 ;
362
403
363
- f ( left_value, right_value)
364
- } ) ,
365
- )
404
+ f ( left_value, right_value)
405
+ } ) ,
406
+ )
407
+ }
366
408
}
367
409
}
368
410
@@ -385,20 +427,19 @@ where
385
427
Self : MappedGenericSequence < T , U > ,
386
428
F : FnMut ( T ) -> U ,
387
429
{
388
- let mut source = ArrayConsumer :: new ( self ) ;
430
+ unsafe {
431
+ let mut source = ArrayConsumer :: new ( self ) ;
389
432
390
- let ArrayConsumer {
391
- ref array,
392
- ref mut position,
393
- } = source;
433
+ let ( array_iter, position) = source. iter_position ( ) ;
394
434
395
- FromIterator :: from_iter ( array . iter ( ) . map ( |src| {
396
- let value = unsafe { ptr:: read ( src) } ;
435
+ FromIterator :: from_iter ( array_iter . map ( |src| {
436
+ let value = ptr:: read ( src) ;
397
437
398
- * position += 1 ;
438
+ * position += 1 ;
399
439
400
- f ( value)
401
- } ) )
440
+ f ( value)
441
+ } ) )
442
+ }
402
443
}
403
444
404
445
#[ inline]
@@ -417,20 +458,19 @@ where
417
458
where
418
459
F : FnMut ( U , T ) -> U ,
419
460
{
420
- let mut source = ArrayConsumer :: new ( self ) ;
461
+ unsafe {
462
+ let mut source = ArrayConsumer :: new ( self ) ;
421
463
422
- let ArrayConsumer {
423
- ref array,
424
- ref mut position,
425
- } = source;
464
+ let ( array_iter, position) = source. iter_position ( ) ;
426
465
427
- array . iter ( ) . fold ( init, |acc, src| {
428
- let value = unsafe { ptr:: read ( src) } ;
466
+ array_iter . fold ( init, |acc, src| {
467
+ let value = ptr:: read ( src) ;
429
468
430
- * position += 1 ;
469
+ * position += 1 ;
431
470
432
- f ( acc, value)
433
- } )
471
+ f ( acc, value)
472
+ } )
473
+ }
434
474
}
435
475
}
436
476
@@ -520,17 +560,21 @@ where
520
560
let iter = iter. into_iter ( ) ;
521
561
522
562
if iter. len ( ) == N :: to_usize ( ) {
523
- let mut destination = ArrayBuilder :: new ( ) ;
563
+ unsafe {
564
+ let mut destination = ArrayBuilder :: new ( ) ;
524
565
525
- for ( dst, src) in destination. array . iter_mut ( ) . zip ( iter. into_iter ( ) ) {
526
- unsafe {
527
- 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
+ }
528
574
}
529
575
530
- destination. position += 1 ;
576
+ Some ( destination. into_inner ( ) )
531
577
}
532
-
533
- Some ( destination. into_inner ( ) )
534
578
} else {
535
579
None
536
580
}
0 commit comments