#[repr(transparent)]
pub struct UserPtr<'a, T: Sized, R: Copy + Repr<T> = *const T> {
v: R,
_phantom: core::marker::PhantomData<&'a T>,
}
impl<'a, T: Sized, R: Copy + Repr<T>> UserPtr<'a, T, R> {
#[inline(always)]
pub unsafe fn from_ptr(ptr: *const T) -> Self {
Self {
v: R::from_ptr(ptr),
_phantom: core::marker::PhantomData,
}
}
#[inline(always)]
pub fn from_ref(r: &'a T) -> Self {
let ptr = r as *const _;
unsafe { Self::from_ptr(ptr) }
}
#[inline(always)]
pub fn repr(&self) -> R {
self.v
}
}
#[repr(transparent)]
pub struct UserMut<'a, T: Sized, R: Copy + ReprMut<T> = *mut T> {
v: R,
_phantom: core::marker::PhantomData<&'a mut T>,
}
impl<'a, T: Sized, R: Copy + ReprMut<T>> UserMut<'a, T, R> {
#[inline(always)]
pub unsafe fn from_ptr(ptr: *mut T) -> Self {
Self {
v: R::from_mut_ptr(ptr),
_phantom: core::marker::PhantomData,
}
}
#[inline(always)]
pub fn from_ref(r: &'a mut T) -> Self {
let ptr = r as *mut _;
unsafe { Self::from_ptr(ptr) }
}
#[inline(always)]
pub fn repr(&self) -> R {
self.v
}
}
pub unsafe trait Repr<T> {
fn from_ptr(ptr: *const T) -> Self;
}
pub unsafe trait ReprMut<T> {
fn from_mut_ptr(ptr: *mut T) -> Self;
}
unsafe impl<T> Repr<T> for *const T {
#[inline(always)]
fn from_ptr(ptr: *const T) -> Self {
ptr
}
}
unsafe impl<T> ReprMut<T> for *mut T {
#[inline(always)]
fn from_mut_ptr(ptr: *mut T) -> Self {
ptr as *mut T
}
}
unsafe impl<T> Repr<T> for u64 {
#[inline(always)]
fn from_ptr(ptr: *const T) -> Self {
ptr as u64
}
}
unsafe impl<T> ReprMut<T> for u64 {
#[inline(always)]
fn from_mut_ptr(ptr: *mut T) -> Self {
ptr as u64
}
}
unsafe impl<T> Repr<T> for usize {
#[inline(always)]
fn from_ptr(ptr: *const T) -> Self {
ptr as usize
}
}
unsafe impl<T> ReprMut<T> for usize {
#[inline(always)]
fn from_mut_ptr(ptr: *mut T) -> Self {
ptr as usize
}
}
#[cfg(test)]
#[allow(dead_code, unused_variables)]
pub fn ensure_reprs_possible() {
let ptr: UserPtr<u8> = UserPtr::from_ref(&0_u8);
let ptr: UserPtr<u8, *const u8> = UserPtr::from_ref(&0_u8);
let ptr: UserPtr<u8, u64> = UserPtr::from_ref(&0_u8);
let ptr: UserPtr<u8, usize> = UserPtr::from_ref(&0_u8);
let ptr: UserMut<u8> = UserMut::from_ref(&mut 0_u8);
let ptr: UserMut<u8, *mut u8> = UserMut::from_ref(&mut 0_u8);
let ptr: UserMut<u8, u64> = UserMut::from_ref(&mut 0_u8);
let ptr: UserMut<u8, usize> = UserMut::from_ref(&mut 0_u8);
}