@@ -852,7 +852,8 @@ impl<T> [T] {
852852 ///
853853 /// # Panics
854854 ///
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.
856857 ///
857858 /// # Examples
858859 ///
@@ -871,10 +872,12 @@ impl<T> [T] {
871872 #[ inline]
872873 pub fn array_chunks < const N : usize > ( & self ) -> ArrayChunks < ' _ , T , N > {
873874 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 }
878881 }
879882
880883 /// 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> {
54835486#[ derive( Debug ) ]
54845487#[ unstable( feature = "array_chunks" , issue = "none" ) ]
54855488pub struct ArrayChunks < ' a , T : ' a , const N : usize > {
5486- v : & ' a [ T ] ,
5489+ iter : Iter < ' a , [ T ; N ] > ,
54875490 rem : & ' a [ T ] ,
54885491}
54895492
@@ -5501,7 +5504,7 @@ impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
55015504#[ unstable( feature = "array_chunks" , issue = "none" ) ]
55025505impl < T , const N : usize > Clone for ArrayChunks < ' _ , T , N > {
55035506 fn clone ( & self ) -> Self {
5504- ArrayChunks { v : self . v , rem : self . rem }
5507+ ArrayChunks { iter : self . iter . clone ( ) , rem : self . rem }
55055508 }
55065509}
55075510
@@ -5511,84 +5514,47 @@ impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> {
55115514
55125515 #[ inline]
55135516 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 ( )
55235518 }
55245519
55255520 #[ inline]
55265521 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
5527- let n = self . v . len ( ) / N ;
5528- ( n, Some ( n) )
5522+ self . iter . size_hint ( )
55295523 }
55305524
55315525 #[ inline]
55325526 fn count ( self ) -> usize {
5533- self . len ( )
5527+ self . iter . count ( )
55345528 }
55355529
55365530 #[ inline]
55375531 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)
55475533 }
55485534
55495535 #[ inline]
5550- fn last ( mut self ) -> Option < Self :: Item > {
5551- self . next_back ( )
5536+ fn last ( self ) -> Option < Self :: Item > {
5537+ self . iter . last ( )
55525538 }
55535539}
55545540
55555541#[ unstable( feature = "array_chunks" , issue = "none" ) ]
55565542impl < ' a , T , const N : usize > DoubleEndedIterator for ArrayChunks < ' a , T , N > {
55575543 #[ inline]
55585544 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 ( )
55685546 }
55695547
55705548 #[ inline]
55715549 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)
55855551 }
55865552}
55875553
55885554#[ unstable( feature = "array_chunks" , issue = "none" ) ]
55895555impl < T , const N : usize > ExactSizeIterator for ArrayChunks < ' _ , T , N > {
55905556 fn is_empty ( & self ) -> bool {
5591- self . v . is_empty ( )
5557+ self . iter . is_empty ( )
55925558 }
55935559}
55945560
@@ -5602,11 +5568,7 @@ impl<T, const N: usize> FusedIterator for ArrayChunks<'_, T, N> {}
56025568#[ unstable( feature = "array_chunks" , issue = "none" ) ]
56035569unsafe impl < ' a , T , const N : usize > TrustedRandomAccess for ArrayChunks < ' a , T , N > {
56045570 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) }
56105572 }
56115573 fn may_have_side_effect ( ) -> bool {
56125574 false
0 commit comments