jay-compositor 1.15.0

The Jay compositor
use crate::utils::markers::JayClone;
use crate::utils::ptr_ext::MutPtrExt;
use crate::utils::ptr_ext::PtrExt;
use std::cell::UnsafeCell;
use std::fmt::Debug;
use std::fmt::Formatter;
use std::mem;

#[derive(Default)]
pub struct CloneCell<T> {
    data: UnsafeCell<T>,
}

impl<T: JayClone> Clone for CloneCell<T> {
    fn clone(&self) -> Self {
        Self {
            data: UnsafeCell::new(self.get()),
        }
    }
}

impl<T: JayClone + Debug> Debug for CloneCell<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        self.get().fmt(f)
    }
}

impl<T> CloneCell<T> {
    pub const fn new(t: T) -> Self {
        Self {
            data: UnsafeCell::new(t),
        }
    }

    #[inline(always)]
    pub fn get(&self) -> T
    where
        T: JayClone,
    {
        unsafe { self.data.get().deref().clone() }
    }

    #[inline(always)]
    pub fn set(&self, t: T) -> T {
        unsafe { mem::replace(self.data.get().deref_mut(), t) }
    }

    #[inline(always)]
    pub fn take(&self) -> T
    where
        T: Default,
    {
        self.set(T::default())
    }

    #[inline(always)]
    pub fn into_inner(self) -> T {
        self.data.into_inner()
    }
}

impl<T> CloneCell<Option<T>> {
    #[inline(always)]
    pub fn is_some(&self) -> bool {
        unsafe { self.data.get().deref().is_some() }
    }

    #[inline(always)]
    pub fn is_none(&self) -> bool {
        unsafe { self.data.get().deref().is_none() }
    }
}