@@ -356,41 +356,94 @@ where
356356 // newtype for `[T; N]`.
357357 unsafe { slice:: from_raw_parts_mut ( slice. as_mut_ptr ( ) . cast ( ) , len) }
358358 }
359+ }
359360
360- /// Convert the given slice into a reference to a hybrid array.
361+ impl < T , U , V > Array < Array < T , U > , V >
362+ where
363+ U : ArraySize ,
364+ V : ArraySize ,
365+ {
366+ /// Takes a `&mut Array<Array<T, N>,M>`, and flattens it to a `&mut [T]`.
361367 ///
362368 /// # Panics
363369 ///
364- /// Panics if the slice's length doesn't match the array type.
365- #[ deprecated( since = "0.2.0" , note = "use `TryFrom` instead" ) ]
366- #[ inline]
367- pub fn from_slice ( slice : & [ T ] ) -> & Self {
368- slice. try_into ( ) . expect ( "slice length mismatch" )
369- }
370-
371- /// Convert the given mutable slice to a mutable reference to a hybrid array.
370+ /// This panics if the length of the resulting slice would overflow a `usize`.
372371 ///
373- /// # Panics
372+ /// This is only possible when flattening a slice of arrays of zero-sized
373+ /// types, and thus tends to be irrelevant in practice. If
374+ /// `size_of::<T>() > 0`, this will never panic.
374375 ///
375- /// Panics if the slice's length doesn't match the array type.
376- #[ deprecated( since = "0.2.0" , note = "use `TryFrom` instead" ) ]
377- #[ inline]
378- pub fn from_mut_slice ( slice : & mut [ T ] ) -> & mut Self {
379- slice. try_into ( ) . expect ( "slice length mismatch" )
380- }
381-
382- /// Clone the contents of the slice as a new hybrid array.
376+ /// # Examples
377+ ///
378+ /// ```
379+ /// use hybrid_array::{Array, typenum::U3};
380+ ///
381+ /// fn add_5_to_all(slice: &mut [i32]) {
382+ /// for i in slice {
383+ /// *i += 5;
384+ /// }
385+ /// }
386+ ///
387+ /// let mut array: Array<Array<i32, U3>, U3> = Array([Array([1_i32, 2, 3]), Array([4, 5, 6]), Array([7, 8, 9])]);
388+ /// add_5_to_all(array.as_flattened_mut());
389+ /// assert_eq!(array, Array([Array([6, 7, 8]), Array([9, 10, 11]), Array([12, 13, 14])]));
390+ /// ```
391+ pub fn as_flattened_mut ( & mut self ) -> & mut [ T ] {
392+ let len = if size_of :: < T > ( ) == 0 {
393+ self . len ( )
394+ . checked_mul ( U :: USIZE )
395+ . expect ( "slice len overflow" )
396+ } else {
397+ // SAFETY: `self.len() * N` cannot overflow because `self` is
398+ // already in the address space.
399+ unsafe { self . len ( ) . unchecked_mul ( U :: USIZE ) }
400+ } ;
401+ // SAFETY: `[T]` is layout-identical to `[T; U]`
402+ unsafe { slice:: from_raw_parts_mut ( self . as_mut_ptr ( ) . cast ( ) , len) }
403+ }
404+
405+ /// Takes a `&Array<Array<T, N>, >>`, and flattens it to a `&[T]`.
383406 ///
384407 /// # Panics
385408 ///
386- /// Panics if the slice's length doesn't match the array type.
387- #[ deprecated( since = "0.2.0" , note = "use `TryFrom` instead" ) ]
388- #[ inline]
389- pub fn clone_from_slice ( slice : & [ T ] ) -> Self
390- where
391- Self : Clone ,
392- {
393- slice. try_into ( ) . expect ( "slice length mismatch" )
409+ /// This panics if the length of the resulting slice would overflow a `usize`.
410+ ///
411+ /// This is only possible when flattening a slice of arrays of zero-sized
412+ /// types, and thus tends to be irrelevant in practice. If
413+ /// `size_of::<T>() > 0`, this will never panic.
414+ ///
415+ /// # Examples
416+ ///
417+ /// ```
418+ /// use hybrid_array::{Array, typenum::{U0, U2, U3, U5, U10}};
419+ ///
420+ /// let a: Array<Array<usize, U3>, U2> = Array([Array([1, 2, 3]), Array([4, 5, 6])]);
421+ /// assert_eq!(a.as_flattened(), &[1, 2, 3, 4, 5, 6]);
422+ ///
423+ /// let b: Array<Array<usize, U2>, U3> = Array([Array([1, 2]), Array([3, 4]), Array([5, 6])]);
424+ /// assert_eq!(a.as_flattened(), b.as_flattened());
425+ ///
426+ /// let c: Array<[usize; 2], U3> = Array([[1, 2], [3, 4], [5, 6]]);
427+ /// assert_eq!(a.as_flattened(), c.as_flattened());
428+ ///
429+ /// let slice_of_empty_arrays: &Array<Array<i32, U5>, U0> = &Array::from_fn(|_| Array([1, 2, 3, 4, 5]));
430+ /// assert!(slice_of_empty_arrays.as_flattened().is_empty());
431+ ///
432+ /// let empty_slice_of_arrays: &Array<Array<u32, U10>, U0> = &Array([]);
433+ /// assert!(empty_slice_of_arrays.as_flattened().is_empty());
434+ /// ```
435+ pub fn as_flattened ( & self ) -> & [ T ] {
436+ let len = if size_of :: < T > ( ) == 0 {
437+ self . len ( )
438+ . checked_mul ( U :: USIZE )
439+ . expect ( "slice len overflow" )
440+ } else {
441+ // SAFETY: `self.len() * N` cannot overflow because `self` is
442+ // already in the address space.
443+ unsafe { self . len ( ) . unchecked_mul ( U :: USIZE ) }
444+ } ;
445+ // SAFETY: `[T]` is layout-identical to `[T; U]`
446+ unsafe { slice:: from_raw_parts ( self . as_ptr ( ) . cast ( ) , len) }
394447 }
395448}
396449
@@ -937,6 +990,48 @@ where
937990 }
938991}
939992
993+ // Deprecated legacy methods to ease migrations from `generic-array`
994+ impl < T , U > Array < T , U >
995+ where
996+ U : ArraySize ,
997+ {
998+ /// Convert the given slice into a reference to a hybrid array.
999+ ///
1000+ /// # Panics
1001+ ///
1002+ /// Panics if the slice's length doesn't match the array type.
1003+ #[ deprecated( since = "0.2.0" , note = "use `TryFrom` instead" ) ]
1004+ #[ inline]
1005+ pub fn from_slice ( slice : & [ T ] ) -> & Self {
1006+ slice. try_into ( ) . expect ( "slice length mismatch" )
1007+ }
1008+
1009+ /// Convert the given mutable slice to a mutable reference to a hybrid array.
1010+ ///
1011+ /// # Panics
1012+ ///
1013+ /// Panics if the slice's length doesn't match the array type.
1014+ #[ deprecated( since = "0.2.0" , note = "use `TryFrom` instead" ) ]
1015+ #[ inline]
1016+ pub fn from_mut_slice ( slice : & mut [ T ] ) -> & mut Self {
1017+ slice. try_into ( ) . expect ( "slice length mismatch" )
1018+ }
1019+
1020+ /// Clone the contents of the slice as a new hybrid array.
1021+ ///
1022+ /// # Panics
1023+ ///
1024+ /// Panics if the slice's length doesn't match the array type.
1025+ #[ deprecated( since = "0.2.0" , note = "use `TryFrom` instead" ) ]
1026+ #[ inline]
1027+ pub fn clone_from_slice ( slice : & [ T ] ) -> Self
1028+ where
1029+ Self : Clone ,
1030+ {
1031+ slice. try_into ( ) . expect ( "slice length mismatch" )
1032+ }
1033+ }
1034+
9401035#[ cfg( feature = "bytemuck" ) ]
9411036unsafe impl < T , U > Pod for Array < T , U >
9421037where
0 commit comments