use std::raw::TraitObject as TORepr;
use super::{MetaData, IntegerDeltaError, IntegerDeltaErrorImpl, Delta, Ptr};
use crate::unreachable::UncheckedOptionExt as _;
union Trans<T: Copy, U: Copy> {
t: T,
u: U,
}
unsafe impl<T: ?Sized> MetaData for TraitObject<T> {
type Data = *mut ();
#[inline]
fn data(t: &Self) -> Self::Data {
unsafe { Trans::<&Self, TORepr> { t }.u.vtable }
}
#[inline]
unsafe fn compose(ptr: Ptr<u8>, vtable: Self::Data) -> Ptr<Self> {
Trans {
u: TORepr {
data: ptr?.as_ptr() as *mut (),
vtable,
},
}.t
}
}
trait Trait<T: ?Sized> {}
#[repr(transparent)]
pub struct TraitObject<T: ?Sized>(dyn Trait<T>);
impl<T: ?Sized> TraitObject<T> {
pub unsafe fn from_ref(t: &T) -> &Self {
Trans::<&T, &Self> { t: t as _ }.u
}
pub unsafe fn from_mut(t: &mut T) -> &mut Self {
&mut *(Trans::<*mut T, *mut Self> { t: t as _ }.u)
}
pub fn as_ref(&self) -> &T {
unsafe { &*(Trans::<*const Self, *const T> { t: self as _ }.u) }
}
pub fn as_ref_mut(&mut self) -> &mut T {
unsafe { &mut *(Trans::<*mut Self, *mut T> { t: self as _ }.u) }
}
}