use core::ops::{Deref, DerefMut};
use core::pin::Pin;
use crate::RefOnce;
pub mod erased_static;
pub unsafe trait PointerLike {
type Pointee;
fn into_ptr(self) -> *mut Self::Pointee;
unsafe fn from_ptr(ptr: *mut Self::Pointee) -> Self;
}
pub unsafe trait PointerDeref: PointerLike + Deref<Target = Self::Pointee> {}
pub unsafe trait PointerDerefMut: PointerDeref + DerefMut {}
pub unsafe trait PointerIntoInner: PointerDerefMut + DerefMut {
fn into_inner(self) -> Self::Pointee;
}
pub unsafe trait PointerPinUnforgotten: PointerLike + PointerDeref {}
unsafe impl<T> PointerLike for &T {
type Pointee = T;
fn into_ptr(self) -> *mut Self::Pointee {
self as *const T as *mut T
}
unsafe fn from_ptr(ptr: *mut Self::Pointee) -> Self {
unsafe { &*(ptr as *const T) }
}
}
unsafe impl<T> PointerDeref for &T {}
unsafe impl<T> PointerLike for &mut T {
type Pointee = T;
fn into_ptr(self) -> *mut Self::Pointee {
self
}
unsafe fn from_ptr(ptr: *mut Self::Pointee) -> Self {
unsafe { &mut *ptr }
}
}
unsafe impl<T> PointerDeref for &mut T {}
unsafe impl<T> PointerDerefMut for &mut T {}
unsafe impl<T: Unpin> PointerPinUnforgotten for &mut T {}
unsafe impl<T> PointerLike for Box<T> {
type Pointee = T;
fn into_ptr(self) -> *mut Self::Pointee {
Box::into_raw(self)
}
unsafe fn from_ptr(ptr: *mut Self::Pointee) -> Self {
unsafe { Box::from_raw(ptr) }
}
}
unsafe impl<T> PointerDeref for Box<T> {}
unsafe impl<T> PointerDerefMut for Box<T> {}
unsafe impl<T> PointerIntoInner for Box<T> {
fn into_inner(self) -> Self::Pointee {
*self
}
}
unsafe impl<T> PointerPinUnforgotten for Box<T> {}
unsafe impl<T> PointerLike for alloc::rc::Rc<T> {
type Pointee = T;
fn into_ptr(self) -> *mut Self::Pointee {
alloc::rc::Rc::into_raw(self) as *mut T
}
unsafe fn from_ptr(ptr: *mut Self::Pointee) -> Self {
unsafe { alloc::rc::Rc::from_raw(ptr as *const T) }
}
}
unsafe impl<T> PointerDeref for alloc::rc::Rc<T> {}
unsafe impl<T> PointerLike for alloc::sync::Arc<T> {
type Pointee = T;
fn into_ptr(self) -> *mut Self::Pointee {
alloc::sync::Arc::into_raw(self) as *mut T
}
unsafe fn from_ptr(ptr: *mut Self::Pointee) -> Self {
unsafe { alloc::sync::Arc::from_raw(ptr as *const T) }
}
}
unsafe impl<T> PointerDeref for alloc::sync::Arc<T> {}
unsafe impl<Ptr: PointerDeref> PointerLike for Pin<Ptr> {
type Pointee = Ptr::Pointee;
fn into_ptr(self) -> *mut Self::Pointee {
unsafe { Pin::into_inner_unchecked(self) }.into_ptr()
}
unsafe fn from_ptr(ptr: *mut Self::Pointee) -> Self {
unsafe { Pin::new_unchecked(Ptr::from_ptr(ptr)) }
}
}
unsafe impl<Ptr: PointerDeref> PointerDeref for Pin<Ptr> {}
unsafe impl<Ptr: PointerDerefMut> PointerDerefMut for Pin<Ptr> where Ptr::Pointee: Unpin {}
unsafe impl<Ptr: PointerIntoInner> PointerIntoInner for Pin<Ptr>
where
Ptr::Pointee: Unpin,
{
fn into_inner(self) -> Self::Pointee {
unsafe { Pin::into_inner_unchecked(self) }.into_inner()
}
}
unsafe impl<Ptr: PointerDerefMut> PointerPinUnforgotten for Pin<Ptr> {}
unsafe impl<'a, T> PointerLike for RefOnce<'a, T> {
type Pointee = T;
fn into_ptr(self) -> *mut Self::Pointee {
RefOnce::into_raw(self)
}
unsafe fn from_ptr(ptr: *mut Self::Pointee) -> Self {
unsafe { RefOnce::from_raw(ptr) }
}
}
unsafe impl<T> PointerDeref for RefOnce<'_, T> {}
unsafe impl<T> PointerDerefMut for RefOnce<'_, T> {}
unsafe impl<T> PointerIntoInner for RefOnce<'_, T> {
fn into_inner(self) -> Self::Pointee {
RefOnce::into_inner(self)
}
}
unsafe impl<T> PointerPinUnforgotten for RefOnce<'_, T> {}