use std::{
cell::{Cell, Ref, RefCell, RefMut},
ops::{Deref, DerefMut},
sync::{Mutex, MutexGuard},
};
use crossbeam_utils::atomic::AtomicCell;
use rclite::{Arc, Rc};
pub trait RcDeref: Clone {
type Target;
type Ref<'a>: Deref<Target = Self::Target>
where
Self: 'a;
fn rc_deref(&self) -> Self::Ref<'_>;
}
pub trait RcDerefMut: RcDeref {
type MutRef<'a>: DerefMut<Target = Self::Target>
where
Self: 'a;
fn rc_deref_mut(&self) -> Self::MutRef<'_>;
fn try_rc_deref_mut(&self) -> Option<Self::MutRef<'_>>;
}
pub trait SharedCell<T: Copy + Eq>: Clone + From<T> {
fn get(&self) -> T;
fn set(&self, value: T);
fn compare_exchange(&self, current: T, new: T) -> Result<T, T>;
}
pub struct MutRc<T>(Rc<RefCell<T>>);
impl<T> Clone for MutRc<T> {
fn clone(&self) -> Self { Self(self.0.clone()) }
}
impl<T> From<T> for MutRc<T> {
fn from(v: T) -> Self { Self(Rc::new(RefCell::new(v))) }
}
impl<T: Default> Default for MutRc<T> {
fn default() -> Self { T::default().into() }
}
impl<T> RcDeref for MutRc<T> {
type Target = T;
type Ref<'a>
= Ref<'a, T>
where
Self: 'a;
fn rc_deref(&self) -> Self::Ref<'_> { self.0.borrow() }
}
impl<T> RcDerefMut for MutRc<T> {
type MutRef<'a>
= RefMut<'a, T>
where
Self: 'a;
fn rc_deref_mut(&self) -> Self::MutRef<'_> { self.0.borrow_mut() }
fn try_rc_deref_mut(&self) -> Option<Self::MutRef<'_>> { self.0.try_borrow_mut().ok() }
}
pub struct CellRc<T>(Rc<Cell<T>>);
impl<T: Copy> Clone for CellRc<T> {
fn clone(&self) -> Self { Self(self.0.clone()) }
}
impl<T: Copy> From<T> for CellRc<T> {
fn from(v: T) -> Self { Self(Rc::new(Cell::new(v))) }
}
impl<T: Copy + Default> Default for CellRc<T> {
fn default() -> Self { T::default().into() }
}
impl<T: Copy + Eq> SharedCell<T> for CellRc<T> {
fn get(&self) -> T { self.0.get() }
fn set(&self, value: T) { self.0.set(value) }
fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
let old = self.0.get();
if old == current {
self.0.set(new);
Ok(old)
} else {
Err(old)
}
}
}
pub struct MutArc<T>(Arc<Mutex<T>>);
impl<T> Clone for MutArc<T> {
fn clone(&self) -> Self { Self(self.0.clone()) }
}
impl<T> From<T> for MutArc<T> {
fn from(v: T) -> Self { Self(Arc::new(Mutex::new(v))) }
}
impl<T: Default> Default for MutArc<T> {
fn default() -> Self { T::default().into() }
}
impl<T> RcDeref for MutArc<T> {
type Target = T;
type Ref<'a>
= MutexGuard<'a, T>
where
Self: 'a;
fn rc_deref(&self) -> Self::Ref<'_> { self.0.lock().unwrap() }
}
impl<T> RcDerefMut for MutArc<T> {
type MutRef<'a>
= MutexGuard<'a, T>
where
Self: 'a;
fn rc_deref_mut(&self) -> Self::MutRef<'_> { self.0.lock().unwrap() }
fn try_rc_deref_mut(&self) -> Option<Self::MutRef<'_>> { self.0.try_lock().ok() }
}
pub struct CellArc<T>(Arc<AtomicCell<T>>);
impl<T: Copy> Clone for CellArc<T> {
fn clone(&self) -> Self { Self(self.0.clone()) }
}
impl<T: Copy> From<T> for CellArc<T> {
fn from(v: T) -> Self { Self(Arc::new(AtomicCell::new(v))) }
}
impl<T: Copy + Default> Default for CellArc<T> {
fn default() -> Self { T::default().into() }
}
impl<T: Copy + Eq> SharedCell<T> for CellArc<T> {
fn get(&self) -> T { self.0.load() }
fn set(&self, value: T) { self.0.store(value) }
fn compare_exchange(&self, current: T, new: T) -> Result<T, T> {
self.0.compare_exchange(current, new)
}
}