use std::ptr::NonNull;
pub type Ptr<T> = Option<NonNull<T>>;
pub unsafe trait Delta: Copy + Eq {
type Error;
fn sub(a: *mut u8, b: *mut u8) -> Result<Self, Self::Error>;
unsafe fn sub_unchecked(a: *mut u8, b: *mut u8) -> Self;
unsafe fn add(self, a: *const u8) -> *mut u8;
}
pub trait Nullable: Delta {
const NULL: Self;
}
pub unsafe trait MetaData {
type Data: Copy + Eq;
fn data(this: &Self) -> Self::Data;
unsafe fn compose(ptr: Ptr<u8>, data: Self::Data) -> Ptr<Self>;
}
unsafe impl<T> MetaData for T {
type Data = ();
#[inline]
fn data(_: &Self) -> Self::Data {}
#[inline]
unsafe fn compose(ptr: Ptr<u8>, (): Self::Data) -> Ptr<Self> {
ptr.map(NonNull::cast)
}
}
unsafe impl<T> MetaData for [T] {
type Data = usize;
#[inline]
fn data(this: &Self) -> Self::Data {
this.len()
}
#[inline]
unsafe fn compose(ptr: Ptr<u8>, data: Self::Data) -> Ptr<Self> {
Some(NonNull::from(
std::slice::from_raw_parts_mut(
ptr?.as_ptr() as *mut T,
data
)
))
}
}
unsafe impl MetaData for str {
type Data = usize;
#[inline]
fn data(this: &Self) -> Self::Data {
this.len()
}
#[inline]
unsafe fn compose(ptr: Ptr<u8>, data: Self::Data) -> Ptr<Self> {
Some(NonNull::from(
std::str::from_utf8_unchecked_mut(std::slice::from_raw_parts_mut(
ptr?.as_ptr(),
data
))
))
}
}