@@ -24,7 +24,10 @@ use cmp::Ordering;
24
24
use convert:: TryFrom ;
25
25
use fmt;
26
26
use hash:: { Hash , self } ;
27
- use marker:: Unsize ;
27
+ use iter:: { FusedIterator , TrustedLen } ;
28
+ use marker:: { PhantomData , Unsize } ;
29
+ use mem:: { ManuallyDrop , self } ;
30
+ use ptr;
28
31
use slice:: { Iter , IterMut } ;
29
32
30
33
/// Utility trait implemented only on arrays of fixed size
@@ -52,6 +55,7 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
52
55
fn as_slice ( & self ) -> & [ T ] {
53
56
self
54
57
}
58
+
55
59
#[ inline]
56
60
fn as_mut_slice ( & mut self ) -> & mut [ T ] {
57
61
self
@@ -210,6 +214,21 @@ macro_rules! array_impls {
210
214
}
211
215
}
212
216
217
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
218
+ impl <T > IntoIterator for [ T ; $N] {
219
+ type Item = T ;
220
+ type IntoIter = IntoIter <T , Self >;
221
+
222
+ fn into_iter( self ) -> Self :: IntoIter {
223
+ Self :: IntoIter {
224
+ array: ManuallyDrop :: new( self ) ,
225
+ index: 0 ,
226
+ index_back: $N,
227
+ _marker: PhantomData ,
228
+ }
229
+ }
230
+ }
231
+
213
232
// NOTE: some less important impls are omitted to reduce code bloat
214
233
__impl_slice_eq1! { [ A ; $N] , [ B ; $N] }
215
234
__impl_slice_eq2! { [ A ; $N] , [ B ] }
@@ -285,3 +304,171 @@ macro_rules! array_impl_default {
285
304
}
286
305
287
306
array_impl_default ! { 32 , T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T }
307
+
308
+
309
+ /// An iterator that moves out of an array.
310
+ ///
311
+ /// This `struct` is created by the `into_iter` method on [arrays]
312
+ /// (provided by the [`IntoIterator`] trait).
313
+ ///
314
+ /// [arrays]: ../../std/primitive.array.html
315
+ /// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html
316
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
317
+ pub struct IntoIter < T , A : FixedSizeArray < T > > {
318
+ // Invariants: index <= index_back <= array.len()
319
+ // Only values in array[index..index_back] are alive at any given time.
320
+ // Values from array[..index] and array[index_back..] are already moved/dropped.
321
+ array : ManuallyDrop < A > ,
322
+ index : usize ,
323
+ index_back : usize ,
324
+ _marker : PhantomData < T > ,
325
+ }
326
+
327
+ impl < T , A : FixedSizeArray < T > > IntoIter < T , A > {
328
+ /// Returns the remaining items of this iterator as a slice.
329
+ ///
330
+ /// # Examples
331
+ ///
332
+ /// ```
333
+ /// #![feature(array_into_iter)]
334
+ ///
335
+ /// # fn main() {
336
+ /// let array = ['a', 'b', 'c'];
337
+ /// let mut into_iter = array.into_iter();
338
+ /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
339
+ /// let _ = into_iter.next().unwrap();
340
+ /// assert_eq!(into_iter.as_slice(), &['b', 'c']);
341
+ /// # }
342
+ /// ```
343
+ #[ inline]
344
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
345
+ pub fn as_slice ( & self ) -> & [ T ] {
346
+ & self . array . as_slice ( ) [ self . index ..self . index_back ]
347
+ }
348
+
349
+ /// Returns the remaining items of this iterator as a mutable slice.
350
+ ///
351
+ /// # Examples
352
+ ///
353
+ /// ```
354
+ /// #![feature(array_into_iter)]
355
+ ///
356
+ /// # fn main() {
357
+ /// let array = ['a', 'b', 'c'];
358
+ /// let mut into_iter = array.into_iter();
359
+ /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
360
+ /// into_iter.as_mut_slice()[2] = 'z';
361
+ /// assert_eq!(into_iter.next().unwrap(), 'a');
362
+ /// assert_eq!(into_iter.next().unwrap(), 'b');
363
+ /// assert_eq!(into_iter.next().unwrap(), 'z');
364
+ /// # }
365
+ /// ```
366
+ #[ inline]
367
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
368
+ pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
369
+ & mut self . array . as_mut_slice ( ) [ self . index ..self . index_back ]
370
+ }
371
+ }
372
+
373
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
374
+ impl < T , A : FixedSizeArray < T > > Drop for IntoIter < T , A > {
375
+ #[ inline]
376
+ fn drop ( & mut self ) {
377
+ // Drop values that are still alive.
378
+ for p in self . as_mut_slice ( ) {
379
+ unsafe { ptr:: drop_in_place ( p) ; }
380
+ }
381
+ }
382
+ }
383
+
384
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
385
+ impl < T : Clone , A : FixedSizeArray < T > > Clone for IntoIter < T , A > {
386
+ fn clone ( & self ) -> Self {
387
+ unsafe {
388
+ let mut iter = Self {
389
+ array : ManuallyDrop :: new ( mem:: uninitialized ( ) ) ,
390
+ index : 0 ,
391
+ index_back : 0 ,
392
+ _marker : PhantomData ,
393
+ } ;
394
+
395
+ // Clone values that are still alive.
396
+ for ( dst, src) in iter. array . as_mut_slice ( ) . iter_mut ( ) . zip ( self . as_slice ( ) ) {
397
+ ptr:: write ( dst, src. clone ( ) ) ;
398
+ iter. index_back += 1 ;
399
+ }
400
+
401
+ iter
402
+ }
403
+ }
404
+ }
405
+
406
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
407
+ impl < T : fmt:: Debug , A : FixedSizeArray < T > > fmt:: Debug for IntoIter < T , A > {
408
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
409
+ f. debug_tuple ( "IntoIter" )
410
+ . field ( & self . as_slice ( ) )
411
+ . finish ( )
412
+ }
413
+ }
414
+
415
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
416
+ impl < T , A : FixedSizeArray < T > > Iterator for IntoIter < T , A > {
417
+ type Item = T ;
418
+
419
+ #[ inline]
420
+ fn next ( & mut self ) -> Option < T > {
421
+ if self . index < self . index_back {
422
+ let p = & self . array . as_slice ( ) [ self . index ] ;
423
+ self . index += 1 ;
424
+ unsafe { Some ( ptr:: read ( p) ) }
425
+ } else {
426
+ None
427
+ }
428
+ }
429
+
430
+ #[ inline]
431
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
432
+ let len = self . len ( ) ;
433
+ ( len, Some ( len) )
434
+ }
435
+
436
+ #[ inline]
437
+ fn count ( self ) -> usize {
438
+ self . len ( )
439
+ }
440
+ }
441
+
442
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
443
+ impl < T , A : FixedSizeArray < T > > DoubleEndedIterator for IntoIter < T , A > {
444
+ #[ inline]
445
+ fn next_back ( & mut self ) -> Option < T > {
446
+ if self . index < self . index_back {
447
+ self . index_back -= 1 ;
448
+ let p = & self . array . as_slice ( ) [ self . index_back ] ;
449
+ unsafe { Some ( ptr:: read ( p) ) }
450
+ } else {
451
+ None
452
+ }
453
+ }
454
+ }
455
+
456
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
457
+ impl < T , A : FixedSizeArray < T > > ExactSizeIterator for IntoIter < T , A > {
458
+ #[ inline]
459
+ fn len ( & self ) -> usize {
460
+ self . index_back - self . index
461
+ }
462
+
463
+ #[ inline]
464
+ fn is_empty ( & self ) -> bool {
465
+ self . index_back == self . index
466
+ }
467
+ }
468
+
469
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
470
+ impl < T , A : FixedSizeArray < T > > FusedIterator for IntoIter < T , A > { }
471
+
472
+ // #[unstable(feature = "trusted_len", issue = "37572")]
473
+ #[ unstable( feature = "array_into_iter" , issue = "0" ) ]
474
+ unsafe impl < T , A : FixedSizeArray < T > > TrustedLen for IntoIter < T , A > { }
0 commit comments