use core::borrow::{Borrow, BorrowMut};
use core::ops::{Deref, DerefMut};
use core::ptr::NonNull;
macro_rules! opaque {
($name:ident) => {
#[repr(C)]
pub struct $name {
_data: (),
_marker: ::core::marker::PhantomData<(*mut u8, ::core::marker::PhantomPinned)>,
}
};
}
#[repr(transparent)]
pub struct ExternAlloc<T: ExternDrop + ?Sized>(NonNull<T>);
impl<T> ExternAlloc<T>
where
T: ExternDrop + ?Sized,
{
pub unsafe fn from_raw(raw: *mut T) -> ExternAlloc<T> {
ExternAlloc(NonNull::new(raw).expect("ExternAlloc ptr is null!"))
}
}
pub unsafe trait ExternDrop {
fn destroy(obj: NonNull<Self>);
}
impl<T> Drop for ExternAlloc<T>
where
T: ExternDrop + ?Sized,
{
fn drop(&mut self) {
T::destroy(self.0);
}
}
impl<T> Deref for ExternAlloc<T>
where
T: ExternDrop + ?Sized,
{
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.0.as_ptr() }
}
}
impl<T> DerefMut for ExternAlloc<T>
where
T: ExternDrop + ?Sized,
{
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.0.as_ptr() }
}
}
impl<T> AsRef<T> for ExternAlloc<T>
where
T: ExternDrop + ?Sized,
{
fn as_ref(&self) -> &T {
&**self
}
}
impl<T> AsMut<T> for ExternAlloc<T>
where
T: ExternDrop + ?Sized,
{
fn as_mut(&mut self) -> &mut T {
&mut **self
}
}
impl<T> Borrow<T> for ExternAlloc<T>
where
T: ExternDrop + ?Sized,
{
fn borrow(&self) -> &T {
&**self
}
}
impl<T> BorrowMut<T> for ExternAlloc<T>
where
T: ExternDrop + ?Sized,
{
fn borrow_mut(&mut self) -> &mut T {
&mut **self
}
}