@@ -680,7 +680,7 @@ impl<T> [T] {
680
680
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
681
681
#[ inline]
682
682
pub fn windows ( & self , size : usize ) -> Windows < ' _ , T > {
683
- assert ! ( size != 0 ) ;
683
+ assert_ne ! ( size, 0 ) ;
684
684
Windows { v : self , size }
685
685
}
686
686
@@ -714,7 +714,7 @@ impl<T> [T] {
714
714
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
715
715
#[ inline]
716
716
pub fn chunks ( & self , chunk_size : usize ) -> Chunks < ' _ , T > {
717
- assert ! ( chunk_size != 0 ) ;
717
+ assert_ne ! ( chunk_size, 0 ) ;
718
718
Chunks { v : self , chunk_size }
719
719
}
720
720
@@ -752,7 +752,7 @@ impl<T> [T] {
752
752
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
753
753
#[ inline]
754
754
pub fn chunks_mut ( & mut self , chunk_size : usize ) -> ChunksMut < ' _ , T > {
755
- assert ! ( chunk_size != 0 ) ;
755
+ assert_ne ! ( chunk_size, 0 ) ;
756
756
ChunksMut { v : self , chunk_size }
757
757
}
758
758
@@ -789,7 +789,7 @@ impl<T> [T] {
789
789
#[ stable( feature = "chunks_exact" , since = "1.31.0" ) ]
790
790
#[ inline]
791
791
pub fn chunks_exact ( & self , chunk_size : usize ) -> ChunksExact < ' _ , T > {
792
- assert ! ( chunk_size != 0 ) ;
792
+ assert_ne ! ( chunk_size, 0 ) ;
793
793
let rem = self . len ( ) % chunk_size;
794
794
let len = self . len ( ) - rem;
795
795
let ( fst, snd) = self . split_at ( len) ;
@@ -834,13 +834,52 @@ impl<T> [T] {
834
834
#[ stable( feature = "chunks_exact" , since = "1.31.0" ) ]
835
835
#[ inline]
836
836
pub fn chunks_exact_mut ( & mut self , chunk_size : usize ) -> ChunksExactMut < ' _ , T > {
837
- assert ! ( chunk_size != 0 ) ;
837
+ assert_ne ! ( chunk_size, 0 ) ;
838
838
let rem = self . len ( ) % chunk_size;
839
839
let len = self . len ( ) - rem;
840
840
let ( fst, snd) = self . split_at_mut ( len) ;
841
841
ChunksExactMut { v : fst, rem : snd, chunk_size }
842
842
}
843
843
844
+ /// Returns an iterator over `N` elements of the slice at a time, starting at the
845
+ /// beginning of the slice.
846
+ ///
847
+ /// The chunks are slices and do not overlap. If `N` does not divide the length of the
848
+ /// slice, then the last up to `N-1` elements will be omitted and can be retrieved
849
+ /// from the `remainder` function of the iterator.
850
+ ///
851
+ /// This method is the const generic equivalent of [`chunks_exact`].
852
+ ///
853
+ /// # Panics
854
+ ///
855
+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
856
+ /// error before this method gets stabilized.
857
+ ///
858
+ /// # Examples
859
+ ///
860
+ /// ```
861
+ /// #![feature(array_chunks)]
862
+ /// let slice = ['l', 'o', 'r', 'e', 'm'];
863
+ /// let mut iter = slice.array_chunks();
864
+ /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
865
+ /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
866
+ /// assert!(iter.next().is_none());
867
+ /// assert_eq!(iter.remainder(), &['m']);
868
+ /// ```
869
+ ///
870
+ /// [`chunks_exact`]: #method.chunks_exact
871
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
872
+ #[ inline]
873
+ pub fn array_chunks < const N : usize > ( & self ) -> ArrayChunks < ' _ , T , N > {
874
+ assert_ne ! ( N , 0 ) ;
875
+ let len = self . len ( ) / N ;
876
+ let ( fst, snd) = self . split_at ( len * N ) ;
877
+ // SAFETY: We cast a slice of `len * N` elements into
878
+ // a slice of `len` many `N` elements chunks.
879
+ let array_slice: & [ [ T ; N ] ] = unsafe { from_raw_parts ( fst. as_ptr ( ) . cast ( ) , len) } ;
880
+ ArrayChunks { iter : array_slice. iter ( ) , rem : snd }
881
+ }
882
+
844
883
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
845
884
/// of the slice.
846
885
///
@@ -5432,6 +5471,110 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
5432
5471
}
5433
5472
}
5434
5473
5474
+ /// An iterator over a slice in (non-overlapping) chunks (`N` elements at a
5475
+ /// time), starting at the beginning of the slice.
5476
+ ///
5477
+ /// When the slice len is not evenly divided by the chunk size, the last
5478
+ /// up to `chunk_size-1` elements will be omitted but can be retrieved from
5479
+ /// the [`remainder`] function from the iterator.
5480
+ ///
5481
+ /// This struct is created by the [`array_chunks`] method on [slices].
5482
+ ///
5483
+ /// [`array_chunks`]: ../../std/primitive.slice.html#method.array_chunks
5484
+ /// [`remainder`]: ../../std/slice/struct.ArrayChunks.html#method.remainder
5485
+ /// [slices]: ../../std/primitive.slice.html
5486
+ #[ derive( Debug ) ]
5487
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5488
+ pub struct ArrayChunks < ' a , T : ' a , const N : usize > {
5489
+ iter : Iter < ' a , [ T ; N ] > ,
5490
+ rem : & ' a [ T ] ,
5491
+ }
5492
+
5493
+ impl < ' a , T , const N : usize > ArrayChunks < ' a , T , N > {
5494
+ /// Returns the remainder of the original slice that is not going to be
5495
+ /// returned by the iterator. The returned slice has at most `chunk_size-1`
5496
+ /// elements.
5497
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5498
+ pub fn remainder ( & self ) -> & ' a [ T ] {
5499
+ self . rem
5500
+ }
5501
+ }
5502
+
5503
+ // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
5504
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5505
+ impl < T , const N : usize > Clone for ArrayChunks < ' _ , T , N > {
5506
+ fn clone ( & self ) -> Self {
5507
+ ArrayChunks { iter : self . iter . clone ( ) , rem : self . rem }
5508
+ }
5509
+ }
5510
+
5511
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5512
+ impl < ' a , T , const N : usize > Iterator for ArrayChunks < ' a , T , N > {
5513
+ type Item = & ' a [ T ; N ] ;
5514
+
5515
+ #[ inline]
5516
+ fn next ( & mut self ) -> Option < & ' a [ T ; N ] > {
5517
+ self . iter . next ( )
5518
+ }
5519
+
5520
+ #[ inline]
5521
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
5522
+ self . iter . size_hint ( )
5523
+ }
5524
+
5525
+ #[ inline]
5526
+ fn count ( self ) -> usize {
5527
+ self . iter . count ( )
5528
+ }
5529
+
5530
+ #[ inline]
5531
+ fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
5532
+ self . iter . nth ( n)
5533
+ }
5534
+
5535
+ #[ inline]
5536
+ fn last ( self ) -> Option < Self :: Item > {
5537
+ self . iter . last ( )
5538
+ }
5539
+ }
5540
+
5541
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5542
+ impl < ' a , T , const N : usize > DoubleEndedIterator for ArrayChunks < ' a , T , N > {
5543
+ #[ inline]
5544
+ fn next_back ( & mut self ) -> Option < & ' a [ T ; N ] > {
5545
+ self . iter . next_back ( )
5546
+ }
5547
+
5548
+ #[ inline]
5549
+ fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
5550
+ self . iter . nth_back ( n)
5551
+ }
5552
+ }
5553
+
5554
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5555
+ impl < T , const N : usize > ExactSizeIterator for ArrayChunks < ' _ , T , N > {
5556
+ fn is_empty ( & self ) -> bool {
5557
+ self . iter . is_empty ( )
5558
+ }
5559
+ }
5560
+
5561
+ #[ unstable( feature = "trusted_len" , issue = "37572" ) ]
5562
+ unsafe impl < T , const N : usize > TrustedLen for ArrayChunks < ' _ , T , N > { }
5563
+
5564
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5565
+ impl < T , const N : usize > FusedIterator for ArrayChunks < ' _ , T , N > { }
5566
+
5567
+ #[ doc( hidden) ]
5568
+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5569
+ unsafe impl < ' a , T , const N : usize > TrustedRandomAccess for ArrayChunks < ' a , T , N > {
5570
+ unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ; N ] {
5571
+ unsafe { self . iter . get_unchecked ( i) }
5572
+ }
5573
+ fn may_have_side_effect ( ) -> bool {
5574
+ false
5575
+ }
5576
+ }
5577
+
5435
5578
/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
5436
5579
/// time), starting at the end of the slice.
5437
5580
///
0 commit comments