@@ -852,7 +852,8 @@ impl<T> [T] {
852
852
///
853
853
/// # Panics
854
854
///
855
- /// Panics if `N` is 0.
855
+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
856
+ /// error before this method gets stabilized.
856
857
///
857
858
/// # Examples
858
859
///
@@ -871,10 +872,12 @@ impl<T> [T] {
871
872
#[ inline]
872
873
pub fn array_chunks < const N : usize > ( & self ) -> ArrayChunks < ' _ , T , N > {
873
874
assert_ne ! ( N , 0 ) ;
874
- let rem = self . len ( ) % N ;
875
- let len = self . len ( ) - rem;
876
- let ( fst, snd) = self . split_at ( len) ;
877
- ArrayChunks { v : fst, rem : snd }
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 }
878
881
}
879
882
880
883
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
@@ -5483,7 +5486,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
5483
5486
#[ derive( Debug ) ]
5484
5487
#[ unstable( feature = "array_chunks" , issue = "none" ) ]
5485
5488
pub struct ArrayChunks < ' a , T : ' a , const N : usize > {
5486
- v : & ' a [ T ] ,
5489
+ iter : Iter < ' a , [ T ; N ] > ,
5487
5490
rem : & ' a [ T ] ,
5488
5491
}
5489
5492
@@ -5501,7 +5504,7 @@ impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
5501
5504
#[ unstable( feature = "array_chunks" , issue = "none" ) ]
5502
5505
impl < T , const N : usize > Clone for ArrayChunks < ' _ , T , N > {
5503
5506
fn clone ( & self ) -> Self {
5504
- ArrayChunks { v : self . v , rem : self . rem }
5507
+ ArrayChunks { iter : self . iter . clone ( ) , rem : self . rem }
5505
5508
}
5506
5509
}
5507
5510
@@ -5511,84 +5514,47 @@ impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> {
5511
5514
5512
5515
#[ inline]
5513
5516
fn next ( & mut self ) -> Option < & ' a [ T ; N ] > {
5514
- if self . v . len ( ) < N {
5515
- None
5516
- } else {
5517
- let ( fst, snd) = self . v . split_at ( N ) ;
5518
- self . v = snd;
5519
- // SAFETY: This is safe as fst is exactly N elements long.
5520
- let ptr = fst. as_ptr ( ) as * const [ T ; N ] ;
5521
- unsafe { Some ( & * ptr) }
5522
- }
5517
+ self . iter . next ( )
5523
5518
}
5524
5519
5525
5520
#[ inline]
5526
5521
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
5527
- let n = self . v . len ( ) / N ;
5528
- ( n, Some ( n) )
5522
+ self . iter . size_hint ( )
5529
5523
}
5530
5524
5531
5525
#[ inline]
5532
5526
fn count ( self ) -> usize {
5533
- self . len ( )
5527
+ self . iter . count ( )
5534
5528
}
5535
5529
5536
5530
#[ inline]
5537
5531
fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
5538
- let ( start, overflow) = n. overflowing_mul ( N ) ;
5539
- if start >= self . v . len ( ) || overflow {
5540
- self . v = & [ ] ;
5541
- None
5542
- } else {
5543
- let ( _, snd) = self . v . split_at ( start) ;
5544
- self . v = snd;
5545
- self . next ( )
5546
- }
5532
+ self . iter . nth ( n)
5547
5533
}
5548
5534
5549
5535
#[ inline]
5550
- fn last ( mut self ) -> Option < Self :: Item > {
5551
- self . next_back ( )
5536
+ fn last ( self ) -> Option < Self :: Item > {
5537
+ self . iter . last ( )
5552
5538
}
5553
5539
}
5554
5540
5555
5541
#[ unstable( feature = "array_chunks" , issue = "none" ) ]
5556
5542
impl < ' a , T , const N : usize > DoubleEndedIterator for ArrayChunks < ' a , T , N > {
5557
5543
#[ inline]
5558
5544
fn next_back ( & mut self ) -> Option < & ' a [ T ; N ] > {
5559
- if self . v . len ( ) < N {
5560
- None
5561
- } else {
5562
- let ( fst, snd) = self . v . split_at ( self . v . len ( ) - N ) ;
5563
- self . v = fst;
5564
- // SAFETY: This is safe as snd is exactly N elements long.
5565
- let ptr = snd. as_ptr ( ) as * const [ T ; N ] ;
5566
- unsafe { Some ( & * ptr) }
5567
- }
5545
+ self . iter . next_back ( )
5568
5546
}
5569
5547
5570
5548
#[ inline]
5571
5549
fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
5572
- let len = self . len ( ) ;
5573
- if n >= len {
5574
- self . v = & [ ] ;
5575
- None
5576
- } else {
5577
- let start = ( len - 1 - n) * N ;
5578
- let end = start + N ;
5579
- let nth_back = & self . v [ start..end] ;
5580
- self . v = & self . v [ ..start] ;
5581
- // SAFETY: This is safe as snd is exactly N elements long.
5582
- let ptr = nth_back. as_ptr ( ) as * const [ T ; N ] ;
5583
- unsafe { Some ( & * ptr) }
5584
- }
5550
+ self . iter . nth_back ( n)
5585
5551
}
5586
5552
}
5587
5553
5588
5554
#[ unstable( feature = "array_chunks" , issue = "none" ) ]
5589
5555
impl < T , const N : usize > ExactSizeIterator for ArrayChunks < ' _ , T , N > {
5590
5556
fn is_empty ( & self ) -> bool {
5591
- self . v . is_empty ( )
5557
+ self . iter . is_empty ( )
5592
5558
}
5593
5559
}
5594
5560
@@ -5602,11 +5568,7 @@ impl<T, const N: usize> FusedIterator for ArrayChunks<'_, T, N> {}
5602
5568
#[ unstable( feature = "array_chunks" , issue = "none" ) ]
5603
5569
unsafe impl < ' a , T , const N : usize > TrustedRandomAccess for ArrayChunks < ' a , T , N > {
5604
5570
unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a [ T ; N ] {
5605
- let start = i * N ;
5606
- // SAFETY: This is safe as `i` must be less than `self.size_hint`.
5607
- let segment = unsafe { from_raw_parts ( self . v . as_ptr ( ) . add ( start) , N ) } ;
5608
- // SAFETY: This is safe as segment is exactly `N` elements long.
5609
- unsafe { & * ( segment. as_ptr ( ) as * const [ T ; N ] ) }
5571
+ unsafe { self . iter . get_unchecked ( i) }
5610
5572
}
5611
5573
fn may_have_side_effect ( ) -> bool {
5612
5574
false
0 commit comments