use core::{
marker::PhantomData,
ptr::{NonNull, Pointee},
};
use crate::NodePtr;
#[repr(transparent)]
pub struct HeaderOpaqueNodePtr<U>
where
U: ?Sized,
{
mid: NonNull<()>,
_phantom: PhantomData<*mut U>,
}
impl<U> Clone for HeaderOpaqueNodePtr<U>
where
U: ?Sized,
{
fn clone(&self) -> Self {
*self
}
}
impl<U> Copy for HeaderOpaqueNodePtr<U> where U: ?Sized {}
impl<U> HeaderOpaqueNodePtr<U>
where
U: ?Sized,
{
#[must_use]
#[inline]
pub const unsafe fn to_transparent<Header>(self) -> NodePtr<Header, U> {
unsafe { NodePtr::from_value_ptr(self.mid) }
}
#[must_use]
pub const unsafe fn metadata(self) -> <U as Pointee>::Metadata {
let ptr = unsafe { self.mid.byte_sub(size_of::<<U as Pointee>::Metadata>()) }.cast();
unsafe { ptr.read() }
}
#[must_use]
#[inline]
pub const fn value_ptr(self) -> NonNull<()> {
self.mid
}
#[must_use]
#[inline]
pub const unsafe fn from_value_ptr(ptr: NonNull<()>) -> Self {
Self {
mid: ptr,
_phantom: PhantomData,
}
}
#[must_use]
#[inline]
pub const unsafe fn data_ptr(self) -> NonNull<U> {
NonNull::from_raw_parts(
self.value_ptr(),
unsafe { self.metadata() },
)
}
}
impl<Header, U> From<NodePtr<Header, U>> for HeaderOpaqueNodePtr<U>
where
U: ?Sized,
{
#[inline]
fn from(value: NodePtr<Header, U>) -> Self {
value.to_header_opaque()
}
}