mod reference;
mod slice;
#[cfg(feature = "alloc")]
mod cow;
#[cfg(feature = "alloc")]
pub use cow::{Borrowed, CellCowExt, CowPolicy, RetainDecision, Retained};
pub use reference::{MelinoeMut, MelinoeRef};
pub use slice::CellSliceExt;
use core::cell::UnsafeCell;
use core::fmt;
use core::marker::PhantomData;
use crate::token::{InvariantLifetime, ReadPermit, WritePermit};
#[repr(transparent)]
pub struct MelinoeCell<'brand, T: ?Sized> {
_brand: InvariantLifetime<'brand>,
value: UnsafeCell<T>,
}
impl<'brand, T> MelinoeCell<'brand, T> {
#[inline]
#[must_use]
pub const fn new(value: T) -> Self {
Self {
_brand: PhantomData,
value: UnsafeCell::new(value),
}
}
#[inline]
#[must_use]
pub fn into_inner(self) -> T {
self.value.into_inner()
}
#[inline]
pub fn replace<'a, P>(&'a self, value: T, permit: P) -> T
where
P: WritePermit<'brand> + 'a,
{
core::mem::replace(&mut *self.borrow_mut(permit), value)
}
}
impl<'brand, T: ?Sized> MelinoeCell<'brand, T> {
#[inline]
#[must_use]
pub fn from_mut(value: &mut T) -> &mut Self {
unsafe { &mut *(value as *mut T as *mut Self) }
}
#[inline]
pub fn borrow<'a, P>(&'a self, _permit: P) -> MelinoeRef<'a, 'brand, T>
where
P: ReadPermit<'brand> + 'a,
{
MelinoeRef::new(unsafe { &*self.value.get() })
}
#[inline]
pub fn borrow_mut<'a, P>(&'a self, _permit: P) -> MelinoeMut<'a, 'brand, T>
where
P: WritePermit<'brand> + 'a,
{
MelinoeMut::new(unsafe { &mut *self.value.get() })
}
#[inline]
pub fn get_mut(&mut self) -> &mut T {
self.value.get_mut()
}
}
impl<'brand, T> MelinoeCell<'brand, T> {
#[inline]
pub(crate) fn slice_as_unsafe_cell(slice: &[Self]) -> &UnsafeCell<[T]> {
let ptr = slice as *const [MelinoeCell<'brand, T>] as *const UnsafeCell<[T]>;
unsafe { &*ptr }
}
}
unsafe impl<'brand, T: ?Sized + Send> Send for MelinoeCell<'brand, T> {}
unsafe impl<'brand, T: ?Sized + Send + Sync> Sync for MelinoeCell<'brand, T> {}
impl<'brand, T: Default> Default for MelinoeCell<'brand, T> {
#[inline]
fn default() -> Self {
Self::new(T::default())
}
}
impl<'brand, T> From<T> for MelinoeCell<'brand, T> {
#[inline]
fn from(value: T) -> Self {
Self::new(value)
}
}
impl<'brand, T: ?Sized> fmt::Debug for MelinoeCell<'brand, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MelinoeCell").finish_non_exhaustive()
}
}