use std::cell::UnsafeCell;
use std::mem::MaybeUninit;
pub struct LocalCell<T> {
inner: UnsafeCell<T>,
}
impl<T> LocalCell<T> {
#[must_use]
pub const fn new(value: T) -> Self {
Self {
inner: UnsafeCell::new(value),
}
}
pub fn get(&self) -> &T {
unsafe { &*self.inner.get() }
}
#[allow(clippy::mut_from_ref)]
pub fn get_mut(&self) -> &mut T {
unsafe { &mut *self.inner.get() }
}
pub fn as_ptr(&self) -> *mut T {
self.inner.get()
}
}
#[repr(transparent)]
pub struct AlwaysInit<T>(MaybeUninit<T>);
impl<T> AlwaysInit<T> {
#[inline(always)]
pub const fn new(t: T) -> Self {
Self(MaybeUninit::new(t))
}
#[inline(always)]
pub fn write(&mut self, t: T) {
self.0.write(t);
}
#[inline(always)]
pub fn get(&self) -> &T {
unsafe { self.0.assume_init_ref() }
}
#[inline(always)]
pub fn get_mut(&mut self) -> &mut T {
unsafe { self.0.assume_init_mut() }
}
#[inline(always)]
pub unsafe fn drop_in_place(&mut self) {
unsafe { self.0.assume_init_drop() }
}
}
impl<T: Default> Default for AlwaysInit<T> {
#[inline(always)]
fn default() -> Self {
Self::new(T::default())
}
}