pub use phper_alloc::{RefClone, ToRefOwned};
use std::{
borrow::{Borrow, BorrowMut},
fmt::{self},
mem::ManuallyDrop,
ops::{Deref, DerefMut},
};
pub struct EBox<T> {
ptr: *mut T,
}
impl<T> EBox<T> {
pub unsafe fn from_raw(raw: *mut T) -> Self {
Self { ptr: raw }
}
pub(crate) unsafe fn from_raw_cast<U>(raw: *mut U) -> Self {
const {
assert!(size_of::<U>() == size_of::<T>());
}
Self { ptr: raw.cast() }
}
pub fn into_raw(b: EBox<T>) -> *mut T {
ManuallyDrop::new(b).ptr
}
pub(crate) fn into_raw_cast<U>(b: EBox<T>) -> *mut U {
const {
assert!(size_of::<U>() == size_of::<T>());
}
ManuallyDrop::new(b).ptr.cast()
}
}
impl<T: fmt::Debug> fmt::Debug for EBox<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
impl<T> Deref for EBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref().unwrap() }
}
}
impl<T> DerefMut for EBox<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.ptr.as_mut().unwrap() }
}
}
impl<T> Drop for EBox<T> {
fn drop(&mut self) {
unsafe {
self.ptr.drop_in_place();
}
}
}
impl<T> Borrow<T> for EBox<T> {
fn borrow(&self) -> &T {
unsafe { self.ptr.as_ref().unwrap() }
}
}
impl<T> BorrowMut<T> for EBox<T> {
fn borrow_mut(&mut self) -> &mut T {
unsafe { self.ptr.as_mut().unwrap() }
}
}
impl<T> AsRef<T> for EBox<T> {
fn as_ref(&self) -> &T {
unsafe { self.ptr.as_ref().unwrap() }
}
}
impl<T> AsMut<T> for EBox<T> {
fn as_mut(&mut self) -> &mut T {
unsafe { self.ptr.as_mut().unwrap() }
}
}