@@ -996,9 +996,9 @@ impl<T> [T] {
996996 /// Returns an iterator over `N` elements of the slice at a time, starting at the
997997 /// beginning of the slice.
998998 ///
999- /// The chunks are slices and do not overlap. If `N` does not divide the length of the
1000- /// slice, then the last up to `N-1` elements will be omitted and can be retrieved
1001- /// from the `remainder` function of the iterator.
999+ /// The chunks are array references and do not overlap. If `N` does not divide the
1000+ /// length of the slice, then the last up to `N-1` elements will be omitted and can be
1001+ /// retrieved from the `remainder` function of the iterator.
10021002 ///
10031003 /// This method is the const generic equivalent of [`chunks_exact`].
10041004 ///
@@ -1032,6 +1032,49 @@ impl<T> [T] {
10321032 ArrayChunks { iter : array_slice. iter ( ) , rem : snd }
10331033 }
10341034
1035+ /// Returns an iterator over `N` elements of the slice at a time, starting at the
1036+ /// beginning of the slice.
1037+ ///
1038+ /// The chunks are mutable array references and do not overlap. If `N` does not divide
1039+ /// the length of the slice, then the last up to `N-1` elements will be omitted and
1040+ /// can be retrieved from the `into_remainder` function of the iterator.
1041+ ///
1042+ /// This method is the const generic equivalent of [`chunks_exact_mut`].
1043+ ///
1044+ /// # Panics
1045+ ///
1046+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
1047+ /// error before this method gets stabilized.
1048+ ///
1049+ /// # Examples
1050+ ///
1051+ /// ```
1052+ /// #![feature(array_chunks)]
1053+ /// let v = &mut [0, 0, 0, 0, 0];
1054+ /// let mut count = 1;
1055+ ///
1056+ /// for chunk in v.array_chunks_mut() {
1057+ /// *chunk = [count; 2];
1058+ /// count += 1;
1059+ /// }
1060+ /// assert_eq!(v, &[1, 1, 2, 2, 0]);
1061+ /// ```
1062+ ///
1063+ /// [`chunks_exact_mut`]: #method.chunks_exact_mut
1064+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
1065+ #[ inline]
1066+ pub fn array_chunks_mut < const N : usize > ( & mut self ) -> ArrayChunksMut < ' _ , T , N > {
1067+ assert_ne ! ( N , 0 ) ;
1068+ let len = self . len ( ) / N ;
1069+ let ( fst, snd) = self . split_at_mut ( len * N ) ;
1070+ // SAFETY: We cast a slice of `len * N` elements into
1071+ // a slice of `len` many `N` elements chunks.
1072+ unsafe {
1073+ let array_slice: & mut [ [ T ; N ] ] = from_raw_parts_mut ( fst. as_mut_ptr ( ) . cast ( ) , len) ;
1074+ ArrayChunksMut { iter : array_slice. iter_mut ( ) , rem : snd }
1075+ }
1076+ }
1077+
10351078 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
10361079 /// of the slice.
10371080 ///
@@ -5826,7 +5869,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
58265869/// time), starting at the beginning of the slice.
58275870///
58285871/// 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
5872+ /// up to `N -1` elements will be omitted but can be retrieved from
58305873/// the [`remainder`] function from the iterator.
58315874///
58325875/// This struct is created by the [`array_chunks`] method on [slices].
@@ -5843,7 +5886,7 @@ pub struct ArrayChunks<'a, T: 'a, const N: usize> {
58435886
58445887impl < ' a , T , const N : usize > ArrayChunks < ' a , T , N > {
58455888 /// 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`
5889+ /// returned by the iterator. The returned slice has at most `N -1`
58475890 /// elements.
58485891 #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
58495892 pub fn remainder ( & self ) -> & ' a [ T ] {
@@ -5929,6 +5972,105 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N>
59295972 }
59305973}
59315974
5975+ /// An iterator over a slice in (non-overlapping) mutable chunks (`N` elements
5976+ /// at a time), starting at the beginning of the slice.
5977+ ///
5978+ /// When the slice len is not evenly divided by the chunk size, the last
5979+ /// up to `N-1` elements will be omitted but can be retrieved from
5980+ /// the [`into_remainder`] function from the iterator.
5981+ ///
5982+ /// This struct is created by the [`array_chunks_mut`] method on [slices].
5983+ ///
5984+ /// [`array_chunks_mut`]: ../../std/primitive.slice.html#method.array_chunks_mut
5985+ /// [`into_remainder`]: ../../std/slice/struct.ArrayChunksMut.html#method.into_remainder
5986+ /// [slices]: ../../std/primitive.slice.html
5987+ #[ derive( Debug ) ]
5988+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5989+ pub struct ArrayChunksMut < ' a , T : ' a , const N : usize > {
5990+ iter : IterMut < ' a , [ T ; N ] > ,
5991+ rem : & ' a mut [ T ] ,
5992+ }
5993+
5994+ impl < ' a , T , const N : usize > ArrayChunksMut < ' a , T , N > {
5995+ /// Returns the remainder of the original slice that is not going to be
5996+ /// returned by the iterator. The returned slice has at most `N-1`
5997+ /// elements.
5998+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5999+ pub fn into_remainder ( self ) -> & ' a mut [ T ] {
6000+ self . rem
6001+ }
6002+ }
6003+
6004+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6005+ impl < ' a , T , const N : usize > Iterator for ArrayChunksMut < ' a , T , N > {
6006+ type Item = & ' a mut [ T ; N ] ;
6007+
6008+ #[ inline]
6009+ fn next ( & mut self ) -> Option < & ' a mut [ T ; N ] > {
6010+ self . iter . next ( )
6011+ }
6012+
6013+ #[ inline]
6014+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
6015+ self . iter . size_hint ( )
6016+ }
6017+
6018+ #[ inline]
6019+ fn count ( self ) -> usize {
6020+ self . iter . count ( )
6021+ }
6022+
6023+ #[ inline]
6024+ fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
6025+ self . iter . nth ( n)
6026+ }
6027+
6028+ #[ inline]
6029+ fn last ( self ) -> Option < Self :: Item > {
6030+ self . iter . last ( )
6031+ }
6032+
6033+ unsafe fn get_unchecked ( & mut self , i : usize ) -> & ' a mut [ T ; N ] {
6034+ // SAFETY: The safety guarantees of `get_unchecked` are transferred to
6035+ // the caller.
6036+ unsafe { self . iter . get_unchecked ( i) }
6037+ }
6038+ }
6039+
6040+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6041+ impl < ' a , T , const N : usize > DoubleEndedIterator for ArrayChunksMut < ' a , T , N > {
6042+ #[ inline]
6043+ fn next_back ( & mut self ) -> Option < & ' a mut [ T ; N ] > {
6044+ self . iter . next_back ( )
6045+ }
6046+
6047+ #[ inline]
6048+ fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
6049+ self . iter . nth_back ( n)
6050+ }
6051+ }
6052+
6053+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6054+ impl < T , const N : usize > ExactSizeIterator for ArrayChunksMut < ' _ , T , N > {
6055+ fn is_empty ( & self ) -> bool {
6056+ self . iter . is_empty ( )
6057+ }
6058+ }
6059+
6060+ #[ unstable( feature = "trusted_len" , issue = "37572" ) ]
6061+ unsafe impl < T , const N : usize > TrustedLen for ArrayChunksMut < ' _ , T , N > { }
6062+
6063+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6064+ impl < T , const N : usize > FusedIterator for ArrayChunksMut < ' _ , T , N > { }
6065+
6066+ #[ doc( hidden) ]
6067+ #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
6068+ unsafe impl < ' a , T , const N : usize > TrustedRandomAccess for ArrayChunksMut < ' a , T , N > {
6069+ fn may_have_side_effect ( ) -> bool {
6070+ false
6071+ }
6072+ }
6073+
59326074/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
59336075/// time), starting at the end of the slice.
59346076///
0 commit comments