@@ -3031,6 +3031,61 @@ impl<T, A: Allocator> Vec<T, A> {
3031
3031
( initialized, spare, & mut self . len )
3032
3032
}
3033
3033
}
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
+ }
3034
3089
}
3035
3090
3036
3091
impl < T : Clone , A : Allocator > Vec < T , A > {
0 commit comments