use core::mem::MaybeUninit;
use crate::{Array, ArrayExt, SizeError};
pub trait Slice {
type Item;
fn copied<A>(&self) -> Result<A, SizeError>
where
A: Array<Item = Self::Item>,
A::Item: Copy;
fn cloned<A>(&self) -> Result<A, SizeError>
where
A: Array<Item = Self::Item>,
A::Item: Clone;
}
pub trait MaybeUninitSlice:
Slice<Item = MaybeUninit<<Self as MaybeUninitSlice>::InitItem>>
{
type InitItem;
unsafe fn assume_init(&self) -> &[Self::InitItem];
unsafe fn assume_init_mut(&mut self) -> &mut [Self::InitItem];
fn from_init(init: &[Self::InitItem]) -> &Self;
fn from_init_mut(init: &mut [Self::InitItem]) -> &mut Self;
}
impl<T> Slice for [T] {
type Item = T;
#[inline]
fn copied<A>(&self) -> Result<A, SizeError>
where
A: Array<Item = Self::Item>,
A::Item: Copy,
{
A::from_slice(self)
}
#[inline]
fn cloned<A>(&self) -> Result<A, SizeError>
where
A: Array<Item = Self::Item>,
A::Item: Clone,
{
A::clone_from_slice(self)
}
}
impl<T> MaybeUninitSlice for [MaybeUninit<T>] {
type InitItem = T;
#[inline]
unsafe fn assume_init(&self) -> &[Self::InitItem] {
&*(self as *const [MaybeUninit<T>] as *const [T])
}
#[inline]
unsafe fn assume_init_mut(&mut self) -> &mut [Self::InitItem] {
&mut *(self as *mut [MaybeUninit<T>] as *mut [T])
}
#[inline]
fn from_init(init: &[Self::InitItem]) -> &Self {
unsafe { &*(init as *const [T] as *const [MaybeUninit<T>]) }
}
#[inline]
fn from_init_mut(init: &mut [Self::InitItem]) -> &mut Self {
unsafe { &mut *(init as *mut [T] as *mut [MaybeUninit<T>]) }
}
}