use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
pub unsafe trait OpaquePtr {
type SysPointee;
type Pointee;
}
#[repr(transparent)]
pub struct Ref<'a, P>
where
P: OpaquePtr,
{
ptr: *const P::SysPointee,
_o: PhantomData<&'a ()>,
_p: PhantomData<P::Pointee>,
}
impl<'a, P> Ref<'a, P>
where
P: OpaquePtr,
{
pub(crate) fn new(ptr: *const P::SysPointee) -> Ref<'a, P> {
Ref {
ptr,
_o: PhantomData,
_p: PhantomData,
}
}
}
#[repr(transparent)]
pub struct RefMut<'a, P>
where
P: OpaquePtr,
{
ptr: *mut P::SysPointee,
_o: PhantomData<&'a ()>,
_p: PhantomData<P::Pointee>,
}
impl<'a, P> RefMut<'a, P>
where
P: OpaquePtr,
{
pub(crate) fn new(ptr: *mut P::SysPointee) -> RefMut<'a, P> {
RefMut {
ptr,
_o: PhantomData,
_p: PhantomData,
}
}
}
impl<'a, P> Deref for Ref<'a, P>
where
P: OpaquePtr,
{
type Target = P::Pointee;
fn deref(&self) -> &Self::Target {
unsafe {
&*(&self.ptr as *const *const <P as OpaquePtr>::SysPointee
as *const <P as OpaquePtr>::Pointee)
}
}
}
impl<'a, P> Deref for RefMut<'a, P>
where
P: OpaquePtr,
{
type Target = P::Pointee;
fn deref(&self) -> &Self::Target {
unsafe {
&*(&self.ptr as *const *mut <P as OpaquePtr>::SysPointee
as *const <P as OpaquePtr>::Pointee)
}
}
}
impl<'a, P> DerefMut for RefMut<'a, P>
where
P: OpaquePtr,
{
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
&mut *(&mut self.ptr as *mut *mut <P as OpaquePtr>::SysPointee
as *mut <P as OpaquePtr>::Pointee)
}
}
}