use core::marker::PhantomData;
use core::mem::transmute;
use core::ptr::drop_in_place;
extern crate alloc;
use alloc::alloc::{dealloc, Layout};
#[doc(hidden)]
pub struct JoinedCell<Owner, Dependent> {
pub owner: Owner,
pub dependent: Dependent,
}
#[doc(hidden)]
pub struct UnsafeSelfCell<Owner: 'static, DependentStatic: 'static> {
joined_void_ptr: *mut u8,
owner_marker: PhantomData<Owner>,
dependent_marker: PhantomData<DependentStatic>,
}
impl<Owner, DependentStatic> UnsafeSelfCell<Owner, DependentStatic> {
pub unsafe fn new(joined_void_ptr: *mut u8) -> Self {
Self {
joined_void_ptr,
owner_marker: PhantomData,
dependent_marker: PhantomData,
}
}
pub unsafe fn borrow_owner<'a, Dependent>(&'a self) -> &'a Owner {
let joined_ptr =
transmute::<*mut u8, *mut JoinedCell<Owner, Dependent>>(self.joined_void_ptr);
&(*joined_ptr).owner
}
pub unsafe fn borrow_dependent<'a, Dependent>(&'a self) -> &'a Dependent {
let joined_ptr =
transmute::<*mut u8, *mut JoinedCell<Owner, Dependent>>(self.joined_void_ptr);
&(*joined_ptr).dependent
}
pub unsafe fn borrow_mut<'a, Dependent>(&'a mut self) -> &'a mut JoinedCell<Owner, Dependent> {
let joined_ptr =
transmute::<*mut u8, *mut JoinedCell<Owner, Dependent>>(self.joined_void_ptr);
&mut (*joined_ptr)
}
pub unsafe fn drop_joined<Dependent>(&mut self) {
let joined_ptr =
transmute::<*mut u8, *mut JoinedCell<Owner, Dependent>>(self.joined_void_ptr);
drop_in_place(joined_ptr);
let layout = Layout::new::<JoinedCell<Owner, Dependent>>();
dealloc(self.joined_void_ptr, layout);
}
}
unsafe impl<Owner, DependentStatic> Send for UnsafeSelfCell<Owner, DependentStatic>
where
Owner: Send,
DependentStatic: Send,
{
}
unsafe impl<Owner, DependentStatic> Sync for UnsafeSelfCell<Owner, DependentStatic>
where
Owner: Sync,
DependentStatic: Sync,
{
}