@@ -3031,6 +3031,61 @@ impl<T, A: Allocator> Vec<T, A> {
30313031 ( initialized, spare, & mut self . len )
30323032 }
30333033 }
3034+
3035+ /// Groups every `N` elements in the `Vec<T>` into chunks to produce a `Vec<[T; N]>`, dropping
3036+ /// elements in the remainder. `N` must be greater than zero.
3037+ ///
3038+ /// If the capacity is not a multiple of the chunk size, the buffer will shrink down to the
3039+ /// nearest multiple with a reallocation or deallocation.
3040+ ///
3041+ /// This function can be used to reverse [`Vec::into_flattened`].
3042+ ///
3043+ /// # Examples
3044+ ///
3045+ /// ```
3046+ /// #![feature(vec_into_chunks)]
3047+ ///
3048+ /// let vec = vec![0, 1, 2, 3, 4, 5, 6, 7];
3049+ /// assert_eq!(vec.into_chunks::<3>(), [[0, 1, 2], [3, 4, 5]]);
3050+ ///
3051+ /// let vec = vec![0, 1, 2, 3];
3052+ /// let chunks: Vec<[u8; 10]> = vec.into_chunks();
3053+ /// assert!(chunks.is_empty());
3054+ ///
3055+ /// let flat = vec![0; 8 * 8 * 8];
3056+ /// let reshaped: Vec<[[[u8; 8]; 8]; 8]> = flat.into_chunks().into_chunks().into_chunks();
3057+ /// assert_eq!(reshaped.len(), 1);
3058+ /// ```
3059+ #[ cfg( not( no_global_oom_handling) ) ]
3060+ #[ unstable( feature = "vec_into_chunks" , issue = "142137" ) ]
3061+ pub fn into_chunks < const N : usize > ( mut self ) -> Vec < [ T ; N ] , A > {
3062+ const {
3063+ assert ! ( N != 0 , "chunk size must be greater than zero" ) ;
3064+ }
3065+
3066+ let ( len, cap) = ( self . len ( ) , self . capacity ( ) ) ;
3067+
3068+ let len_remainder = len % N ;
3069+ if len_remainder != 0 {
3070+ self . truncate ( len - len_remainder) ;
3071+ }
3072+
3073+ let cap_remainder = cap % N ;
3074+ if !T :: IS_ZST && cap_remainder != 0 {
3075+ self . buf . shrink_to_fit ( cap - cap_remainder) ;
3076+ }
3077+
3078+ let ( ptr, _, _, alloc) = self . into_raw_parts_with_alloc ( ) ;
3079+
3080+ // SAFETY:
3081+ // - `ptr` and `alloc` were just returned from `self.into_raw_parts_with_alloc()`
3082+ // - `[T; N]` has the same alignment as `T`
3083+ // - `size_of::<[T; N]>() * cap / N == size_of::<T>() * cap`
3084+ // - `len / N <= cap / N` because `len <= cap`
3085+ // - the allocated memory consists of `len / N` valid values of type `[T; N]`
3086+ // - `cap / N` fits the size of the allocated memory after shrinking
3087+ unsafe { Vec :: from_raw_parts_in ( ptr. cast ( ) , len / N , cap / N , alloc) }
3088+ }
30343089}
30353090
30363091impl < T : Clone , A : Allocator > Vec < T , A > {
0 commit comments