@@ -997,9 +997,9 @@ impl<T> [T] {
997
997
/// Returns an iterator over `N` elements of the slice at a time, starting at the
998
998
/// beginning of the slice.
999
999
///
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.
1003
1003
///
1004
1004
/// This method is the const generic equivalent of [`chunks_exact`].
1005
1005
///
@@ -1033,6 +1033,51 @@ impl<T> [T] {
1033
1033
ArrayChunks { iter : array_slice. iter ( ) , rem : snd }
1034
1034
}
1035
1035
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
+
1036
1081
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
1037
1082
/// of the slice.
1038
1083
///
@@ -5826,7 +5871,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
5826
5871
/// time), starting at the beginning of the slice.
5827
5872
///
5828
5873
/// 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
5830
5875
/// the [`remainder`] function from the iterator.
5831
5876
///
5832
5877
/// This struct is created by the [`array_chunks`] method on [slices].
@@ -5843,7 +5888,7 @@ pub struct ArrayChunks<'a, T: 'a, const N: usize> {
5843
5888
5844
5889
impl < ' a , T , const N : usize > ArrayChunks < ' a , T , N > {
5845
5890
/// 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`
5847
5892
/// elements.
5848
5893
#[ unstable( feature = "array_chunks" , issue = "74985" ) ]
5849
5894
pub fn remainder ( & self ) -> & ' a [ T ] {
@@ -5929,6 +5974,102 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N>
5929
5974
}
5930
5975
}
5931
5976
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
+
5932
6073
/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
5933
6074
/// time), starting at the end of the slice.
5934
6075
///
0 commit comments