Skip to content

Commit

Permalink
read: use const generics in src/read/util.rs
Browse files Browse the repository at this point in the history
The MSRV has been bumped past the minimum required for const generics.
  • Loading branch information
nbdd0121 authored and philipc committed Sep 28, 2024
1 parent 7ba06e8 commit 19a9606
Showing 1 changed file with 31 additions and 49 deletions.
80 changes: 31 additions & 49 deletions src/read/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,70 +41,52 @@ pub trait ArrayLike: Sealed {
fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<Self::Item>];
}

// Use macro since const generics can't be used due to MSRV.
macro_rules! impl_array {
() => {};
($n:literal $($rest:tt)*) => {
// SAFETY: does not modify the content in storage.
unsafe impl<T> Sealed for [T; $n] {
type Storage = [MaybeUninit<T>; $n];

fn new_storage() -> Self::Storage {
// SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
unsafe { MaybeUninit::uninit().assume_init() }
}
}
// SAFETY: does not modify the content in storage.
unsafe impl<T, const N: usize> Sealed for [T; N] {
type Storage = [MaybeUninit<T>; N];

impl<T> ArrayLike for [T; $n] {
type Item = T;
fn new_storage() -> Self::Storage {
// SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
unsafe { MaybeUninit::uninit().assume_init() }
}
}

fn as_slice(storage: &Self::Storage) -> &[MaybeUninit<T>] {
storage
}
impl<T, const N: usize> ArrayLike for [T; N] {
type Item = T;

fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<T>] {
storage
}
}
fn as_slice(storage: &Self::Storage) -> &[MaybeUninit<T>] {
storage
}

impl_array!($($rest)*);
fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<T>] {
storage
}
}

// SAFETY: does not modify the content in storage.
#[cfg(feature = "read")]
macro_rules! impl_box {
() => {};
($n:literal $($rest:tt)*) => {
// SAFETY: does not modify the content in storage.
unsafe impl<T> Sealed for Box<[T; $n]> {
type Storage = Box<[MaybeUninit<T>; $n]>;

fn new_storage() -> Self::Storage {
// SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
Box::new(unsafe { MaybeUninit::uninit().assume_init() })
}
}
unsafe impl<T, const N: usize> Sealed for Box<[T; N]> {
type Storage = Box<[MaybeUninit<T>; N]>;

impl<T> ArrayLike for Box<[T; $n]> {
type Item = T;
fn new_storage() -> Self::Storage {
// SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
Box::new(unsafe { MaybeUninit::uninit().assume_init() })
}
}

fn as_slice(storage: &Self::Storage) -> &[MaybeUninit<T>] {
&storage[..]
}
#[cfg(feature = "read")]
impl<T, const N: usize> ArrayLike for Box<[T; N]> {
type Item = T;

fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<T>] {
&mut storage[..]
}
}
fn as_slice(storage: &Self::Storage) -> &[MaybeUninit<T>] {
&storage[..]
}

impl_box!($($rest)*);
fn as_mut_slice(storage: &mut Self::Storage) -> &mut [MaybeUninit<T>] {
&mut storage[..]
}
}

impl_array!(0 1 2 3 4 8 16 32 64 128 192);
#[cfg(feature = "read")]
impl_box!(0 1 2 3 4 8 16 32 64 128 192);

#[cfg(feature = "read")]
unsafe impl<T> Sealed for Vec<T> {
type Storage = Box<[MaybeUninit<T>]>;
Expand Down

0 comments on commit 19a9606

Please sign in to comment.