Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hybrid-array: rename ArrayExt to FromFn #1009

Merged
merged 1 commit into from
Dec 30, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 34 additions & 27 deletions hybrid-array/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ where
where
F: FnMut(usize) -> T,
{
Self(ArrayExt::from_fn(cb))
Self(FromFn::from_fn(cb))
}

/// Create array from a slice.
Expand Down Expand Up @@ -276,7 +276,7 @@ where
U: ArraySize,
{
fn clone(&self) -> Self {
Self(U::ArrayType::<T>::from_fn(|n| self.0.as_ref()[n].clone()))
Self::from_fn(|n| self.0.as_ref()[n].clone())
}
}

Expand Down Expand Up @@ -304,7 +304,7 @@ where
U: ArraySize,
{
fn default() -> Self {
Self(ArrayExt::from_fn(|_| Default::default()))
Self::from_fn(|_| Default::default())
}
}

Expand Down Expand Up @@ -603,29 +603,6 @@ impl<T> SliceOps<T> for [T] {}
impl<T, const N: usize> SliceOps<T> for [T; N] {}
impl<T, U: ArraySize> SliceOps<T> for Array<T, U> {}

/// Extension trait with helper functions for core arrays.
pub trait ArrayExt<T>: Sized {
/// Create array using the given callback function for each element.
fn from_fn<F>(cb: F) -> Self
where
F: FnMut(usize) -> T;
}

impl<T, const N: usize> ArrayExt<T> for [T; N] {
fn from_fn<F>(mut cb: F) -> Self
where
F: FnMut(usize) -> T,
{
let mut idx = 0;

[(); N].map(|_| {
let res = cb(idx);
idx = idx.saturating_add(1); // TODO(tarcieri): better overflow handling?
res
})
}
}

/// Trait which associates a [`usize`] size and `ArrayType` with a
/// `typenum`-provided [`Unsigned`] integer.
///
Expand All @@ -638,7 +615,8 @@ impl<T, const N: usize> ArrayExt<T> for [T; N] {
/// It is implemented only for a number of types defined in [`typenum::consts`].
pub unsafe trait ArraySize: Unsigned {
/// Array type which corresponds to this size.
type ArrayType<T>: ArrayExt<T>
type ArrayType<T>: AssociatedArraySize<Size = Self>
+ FromFn<T>
+ From<Array<T, Self>>
+ Into<Array<T, Self>>
+ IntoIterator<Item = T>
Expand All @@ -651,6 +629,35 @@ pub trait AssociatedArraySize: Sized {
type Size: ArraySize;
}

/// Construct an array type from the given function.
pub trait FromFn<T>: Sized {
/// Create array using the given callback function for each element.
fn from_fn<F>(cb: F) -> Self
where
F: FnMut(usize) -> T;
}

impl<T, U> FromFn<T> for Array<T, U>
where
U: ArraySize,
{
fn from_fn<F>(cb: F) -> Self
where
F: FnMut(usize) -> T,
{
Array::from_fn(cb)
}
}

impl<T, const N: usize> FromFn<T> for [T; N] {
fn from_fn<F>(cb: F) -> Self
where
F: FnMut(usize) -> T,
{
core::array::from_fn(cb)
}
}

/// Splits the shared slice into a slice of `N`-element arrays, starting at the beginning
/// of the slice, and a remainder slice with length strictly less than `N`.
///
Expand Down