From 84ed60794778175111f8c4744f7ba104ddfd1828 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 27 Jan 2024 13:20:25 -0700 Subject: [PATCH] Remove `ArrayOps` and `SliceOps` After #24, #25, and #26, these traits don't really need to exist and have largely been replaced by safe type conversions with appropriate bounds. In lieu of `ArrayOps` we instead can use `U: ArraySize = [T; N]>>` as a bound, which albeit a bit more verbose concretely describes the inner type of `Array` to the compiler. The `cast_slice_(to|from)_core(_mut)` methods previously defined on the trait have been preserved, but as static methods of `Array`, making the change largely a drop in replacement. Places where they were being called as e.g. `ArrayOps::cast_slice_to_core` just need to be called as `Array::cast_slice_to_core` instead. --- src/lib.rs | 34 +++++++++++++++ src/sizes.rs | 38 +---------------- src/traits.rs | 112 +++++--------------------------------------------- 3 files changed, 45 insertions(+), 139 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d0d86d9..f6db666 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -249,6 +249,40 @@ where } } +// Impls which depend on the inner array type being `[T; N]`. +impl Array +where + U: ArraySize = [T; N]>, +{ + /// Transform slice to slice of core array type. + #[inline] + pub fn cast_slice_to_core(slice: &[Self]) -> &[[T; N]] { + // SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]` + unsafe { core::slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) } + } + + /// Transform mutable slice to mutable slice of core array type. + #[inline] + pub fn cast_slice_to_core_mut(slice: &mut [Self]) -> &mut [[T; N]] { + // SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]` + unsafe { core::slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) } + } + + /// Transform slice to slice of core array type. + #[inline] + pub fn cast_slice_from_core(slice: &[[T; N]]) -> &[Self] { + // SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]` + unsafe { core::slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) } + } + + /// Transform mutable slice to mutable slice of core array type. + #[inline] + pub fn cast_slice_from_core_mut(slice: &mut [[T; N]]) -> &mut [Self] { + // SAFETY: `Self` is a `repr(transparent)` newtype for `[T; N]` + unsafe { core::slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) } + } +} + impl Array, U> where U: ArraySize> = [MaybeUninit; N]>, diff --git a/src/sizes.rs b/src/sizes.rs index fb0b89a..d6e7576 100644 --- a/src/sizes.rs +++ b/src/sizes.rs @@ -1,6 +1,6 @@ //! Macros for defining various array sizes, and their associated invocations. -use super::{Array, ArrayOps, ArraySize, AssociatedArraySize}; +use super::{ArraySize, AssociatedArraySize}; macro_rules! impl_array_size { ($($len:expr => $ty:ident),+) => { @@ -12,42 +12,6 @@ macro_rules! impl_array_size { impl AssociatedArraySize for [T; $len] { type Size = typenum::$ty; } - - impl ArrayOps for Array { - const SIZE: usize = $len; - - #[inline] - fn map_to_core_array(self, f: F) -> [U; $len] - where - F: FnMut(T) -> U - { - self.0.map(f) - } - - #[inline] - fn cast_slice_to_core(slice: &[Self]) -> &[[T; $len]] { - // SAFETY: `Self` is a `repr(transparent)` newtype for `[T; $len]` - unsafe { core::slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) } - } - - #[inline] - fn cast_slice_to_core_mut(slice: &mut [Self]) -> &mut [[T; $len]] { - // SAFETY: `Self` is a `repr(transparent)` newtype for `[T; $len]` - unsafe { core::slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) } - } - - #[inline] - fn cast_slice_from_core(slice: &[[T; $len]]) -> &[Self] { - // SAFETY: `Self` is a `repr(transparent)` newtype for `[T; $len]` - unsafe { core::slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) } - } - - #[inline] - fn cast_slice_from_core_mut(slice: &mut [[T; $len]]) -> &mut [Self] { - // SAFETY: `Self` is a `repr(transparent)` newtype for `[T; $len]` - unsafe { core::slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) } - } - } )+ }; } diff --git a/src/traits.rs b/src/traits.rs index a8ed7f7..09c3263 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,6 +1,6 @@ //! Trait definitions. -use crate::{slice_as_chunks, slice_as_chunks_mut, Array, FromFn}; +use crate::{Array, FromFn}; use core::{ borrow::{Borrow, BorrowMut}, ops::{Index, IndexMut, Range}, @@ -23,11 +23,18 @@ pub unsafe trait ArraySize: Unsigned { /// This is always defined to be `[T; N]` where `N` is the same as /// [`ArraySize::USIZE`][`typenum::Unsigned::USIZE`]. type ArrayType: AssociatedArraySize + + AsRef<[T]> + + AsMut<[T]> + + Borrow<[T]> + + BorrowMut<[T]> + From> + FromFn + + Index + + Index> + + IndexMut + + IndexMut> + Into> - + IntoIterator - + SliceOps; + + IntoIterator; } /// Associates an [`ArraySize`] with a given type. @@ -42,102 +49,3 @@ where { type Size = U; } - -/// Array operations which are const generic over a given array size. -pub trait ArrayOps: - Borrow<[T; N]> - + BorrowMut<[T; N]> - + From<[T; N]> - + FromFn - + Into<[T; N]> - + IntoIterator - + Sized - + SliceOps -{ - /// Size of an array as a `usize`. - /// - /// Not to be confused with [`AssociatedArraySize::Size`], which is [`typenum`]-based. - const SIZE: usize; - - /// Returns an array of the same size as `self`, with function `f` applied to each element - /// in order. - fn map_to_core_array(self, f: F) -> [U; N] - where - F: FnMut(T) -> U; - - /// Transform slice to slice of core array type - fn cast_slice_to_core(slice: &[Self]) -> &[[T; N]]; - - /// Transform mutable slice to mutable slice of core array type - fn cast_slice_to_core_mut(slice: &mut [Self]) -> &mut [[T; N]]; - - /// Transform slice to slice of core array type - fn cast_slice_from_core(slice: &[[T; N]]) -> &[Self]; - - /// Transform mutable slice to mutable slice of core array type - fn cast_slice_from_core_mut(slice: &mut [[T; N]]) -> &mut [Self]; -} - -impl ArrayOps for [T; N] { - const SIZE: usize = N; - - #[inline] - fn map_to_core_array(self, f: F) -> [U; N] - where - F: FnMut(T) -> U, - { - self.map(f) - } - - #[inline] - fn cast_slice_to_core(slice: &[Self]) -> &[[T; N]] { - slice - } - - #[inline] - fn cast_slice_to_core_mut(slice: &mut [Self]) -> &mut [[T; N]] { - slice - } - - #[inline] - fn cast_slice_from_core(slice: &[[T; N]]) -> &[Self] { - slice - } - - #[inline] - fn cast_slice_from_core_mut(slice: &mut [[T; N]]) -> &mut [Self] { - slice - } -} - -/// Slice operations which don't have access to a const generic array size. -pub trait SliceOps: - AsRef<[T]> - + AsMut<[T]> - + Borrow<[T]> - + BorrowMut<[T]> - + Index - + Index> - + IndexMut - + IndexMut> -{ - /// Splits the shared slice into a slice of `N`-element arrays. - /// - /// See [`slice_as_chunks`] for more information. - #[inline] - fn as_array_chunks(&self) -> (&[Array], &[T]) { - slice_as_chunks(self.as_ref()) - } - - /// Splits the exclusive slice into a slice of `N`-element arrays. - /// - /// See [`slice_as_chunks_mut`] for more information. - #[inline] - fn as_array_chunks_mut(&mut self) -> (&mut [Array], &mut [T]) { - slice_as_chunks_mut(self.as_mut()) - } -} - -impl SliceOps for [T] {} -impl SliceOps for [T; N] {} -impl SliceOps for Array {}