@@ -997,9 +997,9 @@ impl<T> [T] {
997997 /// Returns an iterator over `N` elements of the slice at a time, starting at the
998998 /// beginning of the slice.
999999 ///
1000- /// The chunks are slices and do not overlap. If `N` does not divide the length of the
1001- /// slice, then the last up to `N-1` elements will be omitted and can be retrieved
1002- /// from the `remainder` function of the iterator.
1000+ /// The chunks are array references and do not overlap. If `N` does not divide the
1001+ /// length of the slice, then the last up to `N-1` elements will be omitted and can be
1002+ /// retrieved from the `remainder` function of the iterator.
10031003 ///
10041004 /// This method is the const generic equivalent of [`chunks_exact`].
10051005 ///
@@ -1033,6 +1033,51 @@ impl<T> [T] {
10331033 ArrayChunks { iter : array_slice. iter ( ) , rem : snd }
10341034 }
10351035
1036+ /// Returns an iterator over `N` elements of the slice at a time, starting at the
1037+ /// beginning of the slice.
1038+ ///
1039+ /// The chunks are mutable array references and do not overlap. If `N` does not divide
1040+ /// the length of the slice, then the last up to `N-1` elements will be omitted and
1041+ /// can be retrieved from the `into_remainder` function of the iterator.
1042+ ///
1043+ /// This method is the const generic equivalent of [`chunks_exact_mut`].
1044+ ///
1045+ /// # Panics
1046+ ///
1047+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
1048+ /// error before this method gets stabilized.
1049+ ///
1050+ /// # Examples
1051+ ///
1052+ /// ```
1053+ /// #![feature(array_chunks)]
1054+ /// let v = &mut [0, 0, 0, 0, 0];
1055+ /// let mut count = 1;
1056+ ///
1057+ /// for chunk in v.array_chunks_mut() {
1058+ /// *chunk = [count; 2];
1059+ /// count += 1;
1060+ /// }
1061+ /// assert_eq!(v, &[1, 1, 2, 2, 0]);
1062+ /// ```
1063+ ///
1064+ /// [`chunks_exact_mut`]: #method.chunks_exact_mut
1065+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
1066+ #[ inline]
1067+ pub fn array_chunks_mut < const N : usize > ( & mut self ) -> ArrayChunksMut < ' _ , T , N > {
1068+ assert_ne ! ( N , 0 ) ;
1069+ let len = self . len ( ) / N ;
1070+ let ( fst_ptr, snd) = {
1071+ // Scope the first slice into a pointer to avoid aliasing the new slice below.
1072+ let ( fst, snd) = self . split_at_mut ( len * N ) ;
1073+ ( fst. as_mut_ptr ( ) , snd)
1074+ } ;
1075+ // SAFETY: We cast a slice of `len * N` elements into
1076+ // a slice of `len` many `N` elements chunks.
1077+ let array_slice: & mut [ [ T ; N ] ] = unsafe { from_raw_parts_mut ( fst_ptr. cast ( ) , len) } ;
1078+ ArrayChunksMut { iter : array_slice. iter_mut ( ) , rem : snd }
1079+ }
1080+
10361081 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
10371082 /// of the slice.
10381083 ///
@@ -5826,7 +5871,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
58265871/// time), starting at the beginning of the slice.
58275872///
58285873/// When the slice len is not evenly divided by the chunk size, the last
5829- /// up to `chunk_size -1` elements will be omitted but can be retrieved from
5874+ /// up to `N -1` elements will be omitted but can be retrieved from
58305875/// the [`remainder`] function from the iterator.
58315876///
58325877/// This struct is created by the [`array_chunks`] method on [slices].
@@ -5843,7 +5888,7 @@ pub struct ArrayChunks<'a, T: 'a, const N: usize> {
58435888
58445889impl < ' a , T , const N : usize > ArrayChunks < ' a , T , N > {
58455890 /// Returns the remainder of the original slice that is not going to be
5846- /// returned by the iterator. The returned slice has at most `chunk_size -1`
5891+ /// returned by the iterator. The returned slice has at most `N -1`
58475892 /// elements.
58485893 #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
58495894 pub fn remainder ( & self ) -> & ' a [ T ] {
@@ -5929,6 +5974,102 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N>
59295974 }
59305975}
59315976
5977+ /// An iterator over a slice in (non-overlapping) mutable chunks (`N` elements
5978+ /// at a time), starting at the beginning of the slice.
5979+ ///
5980+ /// When the slice len is not evenly divided by the chunk size, the last
5981+ /// up to `N-1` elements will be omitted but can be retrieved from
5982+ /// the [`into_remainder`] function from the iterator.
5983+ ///
5984+ /// This struct is created by the [`array_chunks_mut`] method on [slices].
5985+ ///
5986+ /// [`array_chunks_mut`]: ../../std/primitive.slice.html#method.array_chunks_mut
5987+ /// [`into_remainder`]: ../../std/slice/struct.ArrayChunksMut.html#method.into_remainder
5988+ /// [slices]: ../../std/primitive.slice.html
5989+ #[ derive( Debug ) ]
5990+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5991+ pub struct ArrayChunksMut < ' a , T : ' a , const N : usize > {
5992+ iter : IterMut < ' a , [ T ; N ] > ,
5993+ rem : & ' a mut [ T ] ,
5994+ }
5995+
5996+ impl < ' a , T , const N : usize > ArrayChunksMut < ' a , T , N > {
5997+ /// Returns the remainder of the original slice that is not going to be
5998+ /// returned by the iterator. The returned slice has at most `N-1`
5999+ /// elements.
6000+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6001+ pub fn into_remainder ( self ) -> & ' a mut [ T ] {
6002+ self . rem
6003+ }
6004+ }
6005+
6006+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6007+ impl < ' a , T , const N : usize > Iterator for ArrayChunksMut < ' a , T , N > {
6008+ type Item = & ' a mut [ T ; N ] ;
6009+
6010+ #[ inline]
6011+ fn next ( & mut self ) -> Option < & ' a mut [ T ; N ] > {
6012+ self . iter . next ( )
6013+ }
6014+
6015+ #[ inline]
6016+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
6017+ self . iter . size_hint ( )
6018+ }
6019+
6020+ #[ inline]
6021+ fn count ( self ) -> usize {
6022+ self . iter . count ( )
6023+ }
6024+
6025+ #[ inline]
6026+ fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
6027+ self . iter . nth ( n)
6028+ }
6029+
6030+ #[ inline]
6031+ fn last ( self ) -> Option < Self :: Item > {
6032+ self . iter . last ( )
6033+ }
6034+ }
6035+
6036+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6037+ impl < ' a , T , const N : usize > DoubleEndedIterator for ArrayChunksMut < ' a , T , N > {
6038+ #[ inline]
6039+ fn next_back ( & mut self ) -> Option < & ' a mut [ T ; N ] > {
6040+ self . iter . next_back ( )
6041+ }
6042+
6043+ #[ inline]
6044+ fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
6045+ self . iter . nth_back ( n)
6046+ }
6047+ }
6048+
6049+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6050+ impl < T , const N : usize > ExactSizeIterator for ArrayChunksMut < ' _ , T , N > {
6051+ fn is_empty ( & self ) -> bool {
6052+ self . iter . is_empty ( )
6053+ }
6054+ }
6055+
6056+ #[ unstable( feature = "trusted_len" , issue = "37572" ) ]
6057+ unsafe impl < T , const N : usize > TrustedLen for ArrayChunksMut < ' _ , T , N > { }
6058+
6059+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6060+ impl < T , const N : usize > FusedIterator for ArrayChunksMut < ' _ , T , N > { }
6061+
6062+ #[ doc( hidden) ]
6063+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6064+ unsafe impl < ' a , T , const N : usize > TrustedRandomAccess for ArrayChunksMut < ' a , T , N > {
6065+ unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut [ T ; N ] {
6066+ unsafe { self . iter . get_unchecked ( i) }
6067+ }
6068+ fn may_have_side_effect ( ) -> bool {
6069+ false
6070+ }
6071+ }
6072+
59326073/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
59336074/// time), starting at the end of the slice.
59346075///
0 commit comments