diff --git a/src/iter.rs b/src/iter.rs index 01b1b74..281bab1 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -4,7 +4,6 @@ use crate::{Array, ArraySize}; use core::{ fmt, - mem::size_of, slice::{Iter, IterMut}, }; @@ -106,92 +105,3 @@ where self.iter_mut() } } - -impl Array, V> -where - U: ArraySize, - V: ArraySize, -{ - /// Takes a `&mut Array,M>`, and flattens it to a `&mut [T]`. - /// - /// # Panics - /// - /// This panics if the length of the resulting slice would overflow a `usize`. - /// - /// This is only possible when flattening a slice of arrays of zero-sized - /// types, and thus tends to be irrelevant in practice. If - /// `size_of::() > 0`, this will never panic. - /// - /// # Examples - /// - /// ``` - /// use hybrid_array::{Array, typenum::U3}; - /// - /// fn add_5_to_all(slice: &mut [i32]) { - /// for i in slice { - /// *i += 5; - /// } - /// } - /// - /// let mut array: Array, U3> = Array([Array([1_i32, 2, 3]), Array([4, 5, 6]), Array([7, 8, 9])]); - /// add_5_to_all(array.as_flattened_mut()); - /// assert_eq!(array, Array([Array([6, 7, 8]), Array([9, 10, 11]), Array([12, 13, 14])])); - /// ``` - pub fn as_flattened_mut(&mut self) -> &mut [T] { - let len = if size_of::() == 0 { - self.len() - .checked_mul(U::USIZE) - .expect("slice len overflow") - } else { - // SAFETY: `self.len() * N` cannot overflow because `self` is - // already in the address space. - unsafe { self.len().unchecked_mul(U::USIZE) } - }; - // SAFETY: `[T]` is layout-identical to `[T; U]` - unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr().cast(), len) } - } - - /// Takes a `&Array, >>`, and flattens it to a `&[T]`. - /// - /// # Panics - /// - /// This panics if the length of the resulting slice would overflow a `usize`. - /// - /// This is only possible when flattening a slice of arrays of zero-sized - /// types, and thus tends to be irrelevant in practice. If - /// `size_of::() > 0`, this will never panic. - /// - /// # Examples - /// - /// ``` - /// use hybrid_array::{Array, typenum::{U0, U2, U3, U5, U10}}; - /// - /// let a: Array, U2> = Array([Array([1, 2, 3]), Array([4, 5, 6])]); - /// assert_eq!(a.as_flattened(), &[1, 2, 3, 4, 5, 6]); - /// - /// let b: Array, U3> = Array([Array([1, 2]), Array([3, 4]), Array([5, 6])]); - /// assert_eq!(a.as_flattened(), b.as_flattened()); - /// - /// let c: Array<[usize; 2], U3> = Array([[1, 2], [3, 4], [5, 6]]); - /// assert_eq!(a.as_flattened(), c.as_flattened()); - /// - /// let slice_of_empty_arrays: &Array, U0> = &Array::from_fn(|_| Array([1, 2, 3, 4, 5])); - /// assert!(slice_of_empty_arrays.as_flattened().is_empty()); - /// - /// let empty_slice_of_arrays: &Array, U0> = &Array([]); - /// assert!(empty_slice_of_arrays.as_flattened().is_empty()); - /// ``` - pub fn as_flattened(&self) -> &[T] { - let len = if size_of::() == 0 { - self.len() - .checked_mul(U::USIZE) - .expect("slice len overflow") - } else { - // SAFETY: `self.len() * N` cannot overflow because `self` is - // already in the address space. - unsafe { self.len().unchecked_mul(U::USIZE) } - }; - // SAFETY: `[T]` is layout-identical to `[T; U]` - unsafe { core::slice::from_raw_parts(self.as_ptr().cast(), len) } - } -} diff --git a/src/lib.rs b/src/lib.rs index e14319b..1c6e766 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -356,41 +356,94 @@ where // newtype for `[T; N]`. unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), len) } } +} - /// Convert the given slice into a reference to a hybrid array. +impl Array, V> +where + U: ArraySize, + V: ArraySize, +{ + /// Takes a `&mut Array,M>`, and flattens it to a `&mut [T]`. /// /// # Panics /// - /// Panics if the slice's length doesn't match the array type. - #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")] - #[inline] - pub fn from_slice(slice: &[T]) -> &Self { - slice.try_into().expect("slice length mismatch") - } - - /// Convert the given mutable slice to a mutable reference to a hybrid array. + /// This panics if the length of the resulting slice would overflow a `usize`. /// - /// # Panics + /// This is only possible when flattening a slice of arrays of zero-sized + /// types, and thus tends to be irrelevant in practice. If + /// `size_of::() > 0`, this will never panic. /// - /// Panics if the slice's length doesn't match the array type. - #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")] - #[inline] - pub fn from_mut_slice(slice: &mut [T]) -> &mut Self { - slice.try_into().expect("slice length mismatch") - } - - /// Clone the contents of the slice as a new hybrid array. + /// # Examples + /// + /// ``` + /// use hybrid_array::{Array, typenum::U3}; + /// + /// fn add_5_to_all(slice: &mut [i32]) { + /// for i in slice { + /// *i += 5; + /// } + /// } + /// + /// let mut array: Array, U3> = Array([Array([1_i32, 2, 3]), Array([4, 5, 6]), Array([7, 8, 9])]); + /// add_5_to_all(array.as_flattened_mut()); + /// assert_eq!(array, Array([Array([6, 7, 8]), Array([9, 10, 11]), Array([12, 13, 14])])); + /// ``` + pub fn as_flattened_mut(&mut self) -> &mut [T] { + let len = if size_of::() == 0 { + self.len() + .checked_mul(U::USIZE) + .expect("slice len overflow") + } else { + // SAFETY: `self.len() * N` cannot overflow because `self` is + // already in the address space. + unsafe { self.len().unchecked_mul(U::USIZE) } + }; + // SAFETY: `[T]` is layout-identical to `[T; U]` + unsafe { slice::from_raw_parts_mut(self.as_mut_ptr().cast(), len) } + } + + /// Takes a `&Array, >>`, and flattens it to a `&[T]`. /// /// # Panics /// - /// Panics if the slice's length doesn't match the array type. - #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")] - #[inline] - pub fn clone_from_slice(slice: &[T]) -> Self - where - Self: Clone, - { - slice.try_into().expect("slice length mismatch") + /// This panics if the length of the resulting slice would overflow a `usize`. + /// + /// This is only possible when flattening a slice of arrays of zero-sized + /// types, and thus tends to be irrelevant in practice. If + /// `size_of::() > 0`, this will never panic. + /// + /// # Examples + /// + /// ``` + /// use hybrid_array::{Array, typenum::{U0, U2, U3, U5, U10}}; + /// + /// let a: Array, U2> = Array([Array([1, 2, 3]), Array([4, 5, 6])]); + /// assert_eq!(a.as_flattened(), &[1, 2, 3, 4, 5, 6]); + /// + /// let b: Array, U3> = Array([Array([1, 2]), Array([3, 4]), Array([5, 6])]); + /// assert_eq!(a.as_flattened(), b.as_flattened()); + /// + /// let c: Array<[usize; 2], U3> = Array([[1, 2], [3, 4], [5, 6]]); + /// assert_eq!(a.as_flattened(), c.as_flattened()); + /// + /// let slice_of_empty_arrays: &Array, U0> = &Array::from_fn(|_| Array([1, 2, 3, 4, 5])); + /// assert!(slice_of_empty_arrays.as_flattened().is_empty()); + /// + /// let empty_slice_of_arrays: &Array, U0> = &Array([]); + /// assert!(empty_slice_of_arrays.as_flattened().is_empty()); + /// ``` + pub fn as_flattened(&self) -> &[T] { + let len = if size_of::() == 0 { + self.len() + .checked_mul(U::USIZE) + .expect("slice len overflow") + } else { + // SAFETY: `self.len() * N` cannot overflow because `self` is + // already in the address space. + unsafe { self.len().unchecked_mul(U::USIZE) } + }; + // SAFETY: `[T]` is layout-identical to `[T; U]` + unsafe { slice::from_raw_parts(self.as_ptr().cast(), len) } } } @@ -937,6 +990,48 @@ where } } +// Deprecated legacy methods to ease migrations from `generic-array` +impl Array +where + U: ArraySize, +{ + /// Convert the given slice into a reference to a hybrid array. + /// + /// # Panics + /// + /// Panics if the slice's length doesn't match the array type. + #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")] + #[inline] + pub fn from_slice(slice: &[T]) -> &Self { + slice.try_into().expect("slice length mismatch") + } + + /// Convert the given mutable slice to a mutable reference to a hybrid array. + /// + /// # Panics + /// + /// Panics if the slice's length doesn't match the array type. + #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")] + #[inline] + pub fn from_mut_slice(slice: &mut [T]) -> &mut Self { + slice.try_into().expect("slice length mismatch") + } + + /// Clone the contents of the slice as a new hybrid array. + /// + /// # Panics + /// + /// Panics if the slice's length doesn't match the array type. + #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")] + #[inline] + pub fn clone_from_slice(slice: &[T]) -> Self + where + Self: Clone, + { + slice.try_into().expect("slice length mismatch") + } +} + #[cfg(feature = "bytemuck")] unsafe impl Pod for Array where