use crate::anyref::inner::AnyRefInner;
use crate::utils::is_dangling;
use std::any::Any;
use std::mem::offset_of;
use std::ptr;
pub(crate) trait PtrInterface
where
Self: Sized,
{
fn get_mut_inner_ptr(&self) -> *mut AnyRefInner;
unsafe fn from_inner_in(ptr: *mut AnyRefInner) -> Self;
#[inline]
unsafe fn from_ptr_in(ptr: *mut AnyRefInner) -> Self {
unsafe { Self::from_inner_in(ptr) }
}
unsafe fn read_data<T>(&self) -> T {
unsafe { ptr::read(self.as_ptr() as *const T) }
}
fn as_ptr(&self) -> *const dyn Any {
let ptr: *mut AnyRefInner = self.get_mut_inner_ptr();
if is_dangling(ptr) {
ptr as *const dyn Any
} else {
unsafe {
let data_field_ptr = ptr::addr_of!((*ptr).data);
&mut **(*data_field_ptr).lock_exclusive() as *const dyn Any
}
}
}
unsafe fn from_ptr(ptr: *mut AnyRefInner) -> Self {
unsafe { Self::from_ptr_in(ptr) }
}
unsafe fn from_inner(ptr: *mut AnyRefInner) -> Self {
unsafe { Self::from_inner_in(ptr) }
}
#[inline]
unsafe fn from_raw_in<T: ?Sized>(ptr: *const T) -> Self {
let inner_ptr = if is_dangling(ptr) {
ptr as *mut AnyRefInner
} else {
let obj = ptr as *const u8;
let data_offset = offset_of!(AnyRefInner, data);
unsafe { obj.offset(-(data_offset as isize)) as *mut AnyRefInner }
};
unsafe { Self::from_ptr_in(inner_ptr) }
}
}