@@ -2999,6 +2999,58 @@ impl<T, A: Allocator> Vec<T, A> {
29992999 ( initialized, spare, & mut self . len )
30003000 }
30013001 }
3002+
3003+ /// Groups every `N` elements in the `Vec<T>` into chunks to produce a `Vec<[T; N]>`, dropping
3004+ /// elements in the remainder. `N` must be greater than zero.
3005+ ///
3006+ /// If the capacity is not a multiple of the chunk size, the buffer will shrink down to the
3007+ /// nearest multiple with a reallocation or deallocation.
3008+ ///
3009+ /// This function can be used to reverse [`Vec::into_flattened`].
3010+ ///
3011+ /// # Examples
3012+ ///
3013+ /// ```
3014+ /// let vec = vec![0, 1, 2, 3, 4, 5, 6, 7];
3015+ /// assert_eq!(vec.into_chunks::<3>(), [[0, 1, 2], [3, 4, 5]]);
3016+ ///
3017+ /// let vec = vec![0, 1, 2, 3];
3018+ /// let chunks: Vec<[u8; 10]> = vec.into_chunks();
3019+ /// assert!(chunks.is_empty());
3020+ ///
3021+ /// let flat = vec![0; 8 * 8 * 8];
3022+ /// let reshaped: Vec<[[[u8; 8]; 8]; 8]> = flat.into_chunks().into_chunks().into_chunks();
3023+ /// assert_eq!(reshaped.len(), 1);
3024+ /// ```
3025+ #[ unstable( feature = "vec_into_chunks" , issue = "142137" ) ]
3026+ pub fn into_chunks < const N : usize > ( mut self ) -> Vec < [ T ; N ] , A > {
3027+ const {
3028+ assert ! ( N != 0 , "chunk size should be greater than zero" ) ;
3029+ }
3030+
3031+ let ( len, cap) = ( self . len ( ) , self . capacity ( ) ) ;
3032+
3033+ let len_remainder = len % N ;
3034+ if len_remainder != 0 {
3035+ self . truncate ( len - len_remainder) ;
3036+ }
3037+
3038+ let cap_remainder = cap % N ;
3039+ if !T :: IS_ZST && cap_remainder != 0 {
3040+ self . buf . shrink_to_fit ( cap - cap_remainder) ;
3041+ }
3042+
3043+ let ( ptr, _, _, alloc) = self . into_raw_parts_with_alloc ( ) ;
3044+
3045+ // SAFETY:
3046+ // - `ptr` and `alloc` were just returned from `self.into_raw_parts_with_alloc()`
3047+ // - `[T; N]` has the same alignment as `T`
3048+ // - `size_of::<[T; N]>() * cap / N == size_of::<T>() * cap`
3049+ // - `len / N <= cap / N` because `len <= cap`
3050+ // - the allocated memory consists of `len / N` valid values of type `[T; N]`
3051+ // - `cap / N` fits the size of the allocated memory after shrinking
3052+ unsafe { Vec :: from_raw_parts_in ( ptr. cast ( ) , len / N , cap / N , alloc) }
3053+ }
30023054}
30033055
30043056impl < T : Clone , A : Allocator > Vec < T , A > {
0 commit comments