#![no_std]
use core::fmt;
use core::ops::{Deref, DerefMut};
use core::cell::UnsafeCell;
use core::mem::MaybeUninit;
use core::cmp::Ordering;
#[repr(transparent)]
pub struct InitCell<T>(UnsafeCell<MaybeUninit<T>>);
unsafe impl<T: Send> Send for InitCell<T> {}
unsafe impl<T: Sync> Sync for InitCell<T> {}
impl<T> From<T> for InitCell<T> {
fn from(x: T) -> Self { Self::initialized(x) }
}
impl<T: PartialEq> PartialEq for InitCell<T> {
fn eq(&self, rhs: &Self) -> bool { **self == **rhs }
}
impl<T: Eq> Eq for InitCell<T> {}
impl<T: PartialOrd> PartialOrd for InitCell<T> {
fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> { (**self).partial_cmp(&**rhs) }
}
impl<T: Ord> Ord for InitCell<T> {
fn cmp(&self, rhs: &Self) -> Ordering { (**self).cmp(&**rhs) }
}
impl<T: fmt::Debug> fmt::Debug for InitCell<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: fmt::Display> fmt::Display for InitCell<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: core::hash::Hash> core::hash::Hash for InitCell<T> {
fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
(**self).hash(h);
}
}
impl<T> Deref for InitCell<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { (*self.0.get()).assume_init_ref() }
}
}
impl<T> DerefMut for InitCell<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { (*self.0.get()).assume_init_mut() }
}
}
impl<T> InitCell<T> {
pub const unsafe fn new() -> Self { Self(UnsafeCell::new(MaybeUninit::uninit())) }
pub fn initialized(x: T) -> Self { Self(UnsafeCell::new(MaybeUninit::new(x))) }
pub unsafe fn into_inner(cell: Self) -> T { cell.0.into_inner().assume_init() }
pub unsafe fn init(cell: &Self, x: T) {
(*cell.0.get()).write(x);
}
pub unsafe fn set(cell: &Self, x: T) {
*(*cell.0.get()).as_mut_ptr() = x;
}
}