use std::{marker::PhantomData, ptr::NonNull};
#[derive(Clone, Copy)]
pub struct OpaqueUninit<'mem>(*mut u8, PhantomData<&'mem mut ()>);
impl<'mem> OpaqueUninit<'mem> {
pub fn new<T>(ptr: *mut T) -> Self {
Self(ptr as *mut u8, PhantomData)
}
pub fn from_maybe_uninit<T>(borrow: &'mem mut std::mem::MaybeUninit<T>) -> Self {
Self(borrow.as_mut_ptr() as *mut u8, PhantomData)
}
pub unsafe fn assume_init(self) -> Opaque<'mem> {
let ptr = unsafe { NonNull::new_unchecked(self.0) };
Opaque(ptr, PhantomData)
}
pub unsafe fn write<T>(self, value: T) -> Opaque<'mem> {
unsafe {
std::ptr::write(self.0 as *mut T, value);
self.assume_init()
}
}
pub fn as_mut_ptr(self) -> *mut u8 {
self.0
}
pub fn as_ptr(self) -> *const u8 {
self.0
}
pub unsafe fn field_uninit(self, offset: usize) -> OpaqueUninit<'mem> {
OpaqueUninit(unsafe { self.0.byte_add(offset) }, PhantomData)
}
pub unsafe fn field_init(self, offset: usize) -> Opaque<'mem> {
Opaque(
unsafe { NonNull::new_unchecked(self.0.add(offset)) },
PhantomData,
)
}
}
#[derive(Clone, Copy)]
pub struct OpaqueConst<'mem>(NonNull<u8>, PhantomData<&'mem ()>);
impl<'mem> OpaqueConst<'mem> {
pub fn from_ref<T>(r: &'mem T) -> Self {
Self(NonNull::from(r).cast(), PhantomData)
}
pub unsafe fn new_unchecked<T>(ptr: *const T) -> Self {
unsafe { Self(NonNull::new_unchecked(ptr as *mut u8), PhantomData) }
}
pub fn as_byte_ptr(self) -> *const u8 {
self.0.as_ptr()
}
pub unsafe fn as_ptr<T>(self) -> *const T {
self.0.as_ptr() as *const T
}
pub unsafe fn as_ref<'borrow: 'mem, T>(self) -> &'borrow T {
unsafe { &*(self.0.as_ptr() as *const T) }
}
pub unsafe fn field(self, offset: usize) -> OpaqueConst<'mem> {
OpaqueConst(
unsafe { NonNull::new_unchecked(self.0.as_ptr().byte_add(offset)) },
PhantomData,
)
}
}
#[derive(Clone, Copy)]
pub struct Opaque<'mem>(NonNull<u8>, PhantomData<&'mem mut ()>);
impl<'mem> Opaque<'mem> {
pub fn from_ref<T>(r: &'mem mut T) -> Self {
Self(NonNull::from(r).cast(), PhantomData)
}
pub unsafe fn new_unchecked<T>(ptr: *mut T) -> Self {
Self(
unsafe { NonNull::new_unchecked(ptr as *mut u8) },
PhantomData,
)
}
pub fn as_byte_ptr(self) -> *const u8 {
self.0.as_ptr()
}
pub fn as_mut_byte_ptr(self) -> *mut u8 {
self.0.as_ptr()
}
pub unsafe fn as_ptr<T>(self) -> *const T {
self.0.as_ptr() as *const T
}
pub unsafe fn as_mut_ptr<'borrow: 'mem, T>(self) -> &'borrow mut T {
unsafe { &mut *(self.0.as_ptr() as *mut T) }
}
pub unsafe fn as_ref<'borrow: 'mem, T>(self) -> &'borrow T {
unsafe { &*(self.0.as_ptr() as *const T) }
}
pub fn as_const<'borrow: 'mem>(self) -> OpaqueConst<'borrow> {
OpaqueConst(self.0, PhantomData)
}
pub unsafe fn read<T>(self) -> T {
unsafe { std::ptr::read(self.as_mut_ptr()) }
}
pub unsafe fn drop_in_place<T>(self) {
unsafe { std::ptr::drop_in_place(self.as_mut_ptr::<T>()) }
}
}