use std::cell::UnsafeCell;
use std::ops::Deref;
use std::sync::{Arc, Weak};
pub struct Owner<T: ?Sized>(Arc<UnsafeCell<T>>);
#[derive(Clone)]
pub struct Subobject<T: ?Sized>(Arc<UnsafeCell<T>>);
#[derive(Clone)]
pub struct WeakSubobject<T: ?Sized>(Weak<UnsafeCell<T>>);
unsafe impl<T: Send> Send for Owner<T> {}
unsafe impl<T: Sync> Sync for Owner<T> {}
impl<T: std::panic::UnwindSafe> std::panic::UnwindSafe for Owner<T> {}
impl<T: std::panic::RefUnwindSafe> std::panic::RefUnwindSafe for Owner<T> {}
unsafe impl<T: Send> Send for Subobject<T> {}
unsafe impl<T> Sync for Subobject<T> {}
impl<T> std::panic::UnwindSafe for Subobject<T> {}
impl<T> std::panic::RefUnwindSafe for Subobject<T> {}
unsafe impl<T: Send> Send for WeakSubobject<T> {}
unsafe impl<T> Sync for WeakSubobject<T> {}
impl<T> std::panic::UnwindSafe for WeakSubobject<T> {}
impl<T> std::panic::RefUnwindSafe for WeakSubobject<T> {}
impl<T> Owner<T> {
pub fn new(value: T) -> Self {
Self(Arc::new(UnsafeCell::new(value)))
}
pub fn from_arc(mut arc: Arc<T>) -> Result<Self, Arc<T>> {
if Arc::get_mut(&mut arc).is_none() {
return Err(arc);
}
Ok(Self(unsafe { arc_transmute(arc) }))
}
pub fn into_arc(this: Self) -> Arc<T> {
unsafe { arc_transmute(this.0) }
}
pub fn ptr_eq(this: &Self, other: &Subobject<T>) -> bool {
Arc::ptr_eq(&this.0, &other.0)
}
}
impl<T> Subobject<T> {
pub fn new(value: &Owner<T>) -> Subobject<T> {
Subobject(value.0.clone())
}
}
impl<T: Send + Sync + 'static> Subobject<T> {
pub fn erase(self) -> Arc<dyn Send + Sync> {
unsafe { arc_transmute::<UnsafeCell<T>, T>(self.0) }
}
}
impl<T> WeakSubobject<T> {
}
impl<T> std::ops::Deref for Owner<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.0.get() }
}
}
impl<T> std::ops::DerefMut for Owner<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.0.get() }
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for Owner<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Owner").field(self.deref()).finish()
}
}
impl<T> std::fmt::Debug for Subobject<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Subobject").field(&self.0).finish()
}
}
impl<T> std::fmt::Debug for WeakSubobject<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("WeakSubobject").field(&self.0).finish()
}
}
unsafe fn arc_transmute<T, U>(arc: Arc<T>) -> Arc<U> {
Arc::from_raw(Arc::into_raw(arc) as *const U)
}