use core::mem::MaybeUninit;
use crate::wrappers::AssertInit;
#[cfg(feature = "alloc")]
use alloc::{boxed::Box, rc::Rc, string::String, sync::Arc, vec::Vec};
pub unsafe trait Initialize {
type Item;
fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<Self::Item>];
unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<Self::Item>];
}
pub unsafe trait InitializeVectored {
type UninitVector: Initialize;
fn as_maybe_uninit_vectors(&self) -> &[Self::UninitVector];
unsafe fn as_maybe_uninit_vectors_mut(&mut self) -> &mut [Self::UninitVector];
}
pub trait InitializeExt: private2::Sealed + Initialize + Sized {
unsafe fn assume_init(self) -> AssertInit<Self> {
AssertInit::new_unchecked(self)
}
}
mod private2 {
pub trait Sealed {}
}
mod private3 {
pub trait Sealed {}
}
mod private4 {
pub trait Sealed {}
}
mod private5 {
pub trait Sealed {}
}
impl<T> private2::Sealed for T where T: Initialize {}
impl<T> InitializeExt for T where T: Initialize {}
unsafe impl<'a, T> Initialize for &'a mut [MaybeUninit<T>] {
type Item = T;
#[inline]
fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<T>] {
self
}
#[inline]
unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
self
}
}
impl<'a, T> From<AssertInit<&'a mut [MaybeUninit<T>]>> for &'a mut [T] {
#[inline]
fn from(init_slice: AssertInit<&'a mut [MaybeUninit<T>]>) -> &'a mut [T] {
unsafe { crate::cast_uninit_to_init_slice_mut(init_slice.into_inner()) }
}
}
unsafe impl<'a, 'b, T> InitializeVectored for &'a mut [&'b mut [MaybeUninit<T>]] {
type UninitVector = &'b mut [MaybeUninit<T>];
fn as_maybe_uninit_vectors(&self) -> &[Self::UninitVector] {
self
}
unsafe fn as_maybe_uninit_vectors_mut(&mut self) -> &mut [Self::UninitVector] {
self
}
}
#[cfg(feature = "alloc")]
unsafe impl<T> Initialize for Box<[MaybeUninit<T>]> {
type Item = T;
#[inline]
fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<T>] {
self
}
#[inline]
unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
self
}
}
#[cfg(feature = "alloc")]
impl<T> From<AssertInit<Box<[MaybeUninit<T>]>>> for Box<[T]> {
#[inline]
fn from(init_box: AssertInit<Box<[MaybeUninit<T>]>>) -> Box<[T]> {
#[cfg(feature = "nightly")]
unsafe {
#[forbid(unconditional_recursion)]
Box::<[MaybeUninit<T>]>::assume_init(init_box.into_inner())
}
#[cfg(not(feature = "nightly"))]
unsafe {
let slice_ptr = Box::into_raw(init_box.into_inner());
Box::from_raw(crate::cast_uninit_to_init_slice_mut(&mut *slice_ptr))
}
}
}
#[cfg(feature = "alloc")]
impl<T> From<AssertInit<Vec<MaybeUninit<T>>>> for Vec<T> {
#[inline]
fn from(init_vec: AssertInit<Vec<MaybeUninit<T>>>) -> Vec<T> {
unsafe {
let mut vec = init_vec.into_inner();
let (ptr, cap, len) = {
let ptr = vec.as_mut_ptr();
let cap = vec.capacity();
let len = vec.len();
core::mem::forget(vec);
(ptr, cap, len)
};
Vec::from_raw_parts(ptr as *mut T, cap, len)
}
}
}
unsafe impl<T, const N: usize> Initialize for [MaybeUninit<T>; N] {
type Item = T;
#[inline]
fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<T>] {
self
}
#[inline]
unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
self
}
}
impl<T, const N: usize> From<AssertInit<[MaybeUninit<T>; N]>> for [T; N] {
#[inline]
fn from(init: AssertInit<[MaybeUninit<T>; N]>) -> [T; N] {
#[cfg(feature = "nightly")]
unsafe {
MaybeUninit::array_assume_init(init.into_inner())
}
#[cfg(not(feature = "nightly"))]
unsafe {
let inner = init.into_inner();
let init: [T; N] = core::mem::transmute_copy(&inner);
init
}
}
}
pub unsafe trait TrustedDeref: core::ops::Deref {}
unsafe impl<'a, T: ?Sized> TrustedDeref for &'a T {}
unsafe impl<'a, T: ?Sized> TrustedDeref for &'a mut T {}
#[cfg(feature = "alloc")]
unsafe impl<T> TrustedDeref for Vec<T> {}
#[cfg(feature = "alloc")]
unsafe impl<T: ?Sized> TrustedDeref for Box<T> {}
#[cfg(feature = "alloc")]
unsafe impl<T: ?Sized> TrustedDeref for Arc<T> {}
#[cfg(feature = "alloc")]
unsafe impl<T: ?Sized> TrustedDeref for Rc<T> {}
unsafe impl<'a, T: ?Sized> TrustedDeref for core::cell::Ref<'a, T> {}
unsafe impl<'a, T: ?Sized> TrustedDeref for core::cell::RefMut<'a, T> {}
#[cfg(feature = "std")]
unsafe impl<'a, T: ?Sized> TrustedDeref for std::sync::MutexGuard<'a, T> {}
#[cfg(feature = "std")]
unsafe impl<'a, T: ?Sized> TrustedDeref for std::sync::RwLockReadGuard<'a, T> {}
#[cfg(feature = "std")]
unsafe impl<'a, T: ?Sized> TrustedDeref for std::sync::RwLockWriteGuard<'a, T> {}
#[cfg(feature = "alloc")]
unsafe impl TrustedDeref for String {}
#[cfg(feature = "std")]
unsafe impl TrustedDeref for std::ffi::CString {}
#[cfg(feature = "std")]
unsafe impl TrustedDeref for std::ffi::OsString {}
#[cfg(feature = "std")]
unsafe impl TrustedDeref for std::path::PathBuf {}
unsafe impl<T: core::ops::Deref> TrustedDeref for core::pin::Pin<T> {}
#[cfg(feature = "alloc")]
unsafe impl<'a, T: alloc::borrow::ToOwned> TrustedDeref for alloc::borrow::Cow<'a, T> {}
pub unsafe trait Equivalent<T>
where
T: Initialize,
Self: Initialize<Item = <T as Initialize>::Item>,
{
}