use std::ptr;
use std::sync::Arc;
pub unsafe trait RefCnt: Clone {
type Base;
fn into_ptr(me: Self) -> *mut Self::Base;
fn as_ptr(me: &Self) -> *mut Self::Base;
unsafe fn from_ptr(ptr: *const Self::Base) -> Self;
fn inc(me: &Self) {
Self::into_ptr(Self::clone(me));
}
unsafe fn dec(ptr: *const Self::Base) {
drop(Self::from_ptr(ptr));
}
fn can_null() -> bool;
}
pub unsafe trait NonNull: RefCnt {}
unsafe impl<T> RefCnt for Arc<T> {
type Base = T;
fn into_ptr(me: Arc<T>) -> *mut T {
Arc::into_raw(me) as *mut T
}
fn as_ptr(me: &Arc<T>) -> *mut T {
me as &T as *const T as *mut T
}
unsafe fn from_ptr(ptr: *const T) -> Arc<T> {
Arc::from_raw(ptr)
}
fn can_null() -> bool {
false
}
}
unsafe impl<T: NonNull> RefCnt for Option<T> {
type Base = T::Base;
fn into_ptr(me: Option<T>) -> *mut T::Base {
me.map(T::into_ptr).unwrap_or_else(ptr::null_mut)
}
fn as_ptr(me: &Option<T>) -> *mut T::Base {
me.as_ref().map(T::as_ptr).unwrap_or_else(ptr::null_mut)
}
unsafe fn from_ptr(ptr: *const T::Base) -> Option<T> {
if ptr.is_null() {
None
} else {
Some(T::from_ptr(ptr))
}
}
fn can_null() -> bool {
true
}
}
unsafe impl<T> NonNull for Arc<T> {}