use std::{
cell::UnsafeCell,
mem::transmute,
ops::{Deref, DerefMut},
rc::{Rc, Weak},
};
#[derive(Debug, Default)]
pub struct Shared<T>(Rc<UnsafeCell<T>>);
impl<T> Shared<T> {
pub fn new(t: T) -> Shared<T> {
Shared(Rc::new(UnsafeCell::new(t)))
}
pub fn new_cyclic<F>(data_fn: F) -> Self
where
F: FnOnce(&Weak<T>) -> T,
{
let x = unsafe { transmute(Rc::new_cyclic(|m| data_fn(m))) };
Self(x)
}
#[allow(clippy::mut_from_ref)]
pub unsafe fn inner_unsafe(&self) -> &mut T {
&mut (*self.0.get())
}
pub fn clone_inner(&self) -> T
where
T: Clone,
{
self.deref().clone()
}
}
impl<T> Clone for Shared<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> Deref for Shared<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &(*self.0.get()) }
}
}
impl<T> DerefMut for Shared<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut (*self.0.get()) }
}
}