use super::*;
use std::{
fmt,
ops::{Deref,DerefMut},
};
#[allow(unused_imports)]
use core_extensions::SelfOps;
use crate::{
abi_stability::PrefixStableAbi,
erased_types::{
c_functions::adapt_std_fmt,
InterfaceBound,
},
sabi_types::{MaybeCmp,RRef,RMut},
std_types::UTypeId,
pointer_trait::{
CanTransmuteElement,TransmuteElement,
GetPointerKind,PK_SmartPointer,PK_Reference,PointerKind,
},
type_level::{
impl_enum::{Implemented,Unimplemented},
trait_marker,
},
sabi_trait::vtable::{BaseVtable_Ref, BaseVtable_Prefix},
utils::{transmute_reference,transmute_mut_reference},
StableAbi,
};
#[repr(C)]
#[derive(StableAbi)]
#[sabi(
not_stableabi(V),
bound="V:PrefixStableAbi",
bound="I:InterfaceBound",
extra_checks="<I as InterfaceBound>::EXTRA_CHECKS",
)]
pub struct RObject<'lt,P,I,V>
where
P:GetPointerKind
{
vtable:PrefixRef<V>,
ptr: ManuallyDrop<P>,
_marker:PhantomData<(&'lt (),I)>,
}
mod clone_impl{
pub trait CloneImpl<PtrKind>{
fn clone_impl(&self) -> Self;
}
}
use self::clone_impl::CloneImpl;
impl<'lt,P, I,V> CloneImpl<PK_SmartPointer> for RObject<'lt,P,I,V>
where
P: Deref+GetPointerKind,
I: InterfaceType<Clone = Implemented<trait_marker::Clone>>,
{
fn clone_impl(&self) -> Self {
let ptr=unsafe{
self.sabi_robject_vtable()._sabi_clone().unwrap()(&self.ptr)
};
Self{
vtable:self.vtable,
ptr:ManuallyDrop::new(ptr),
_marker:PhantomData,
}
}
}
impl<'lt,P, I,V> CloneImpl<PK_Reference> for RObject<'lt,P,I,V>
where
P: Deref+Copy+GetPointerKind,
I: InterfaceType,
{
fn clone_impl(&self) -> Self {
Self{
vtable:self.vtable,
ptr:ManuallyDrop::new(*self.ptr),
_marker:PhantomData,
}
}
}
impl<'lt,P, I,V> Clone for RObject<'lt,P,I,V>
where
P: Deref+GetPointerKind,
I: InterfaceType,
Self:CloneImpl<<P as GetPointerKind>::Kind>,
{
fn clone(&self) -> Self {
self.clone_impl()
}
}
impl<'lt,P,I,V> Debug for RObject<'lt,P,I,V>
where
P: Deref<Target=()>+GetPointerKind,
I: InterfaceType<Debug = Implemented<trait_marker::Debug>>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe{
adapt_std_fmt::<ErasedObject>(
self.sabi_erased_ref(),
self.sabi_robject_vtable()._sabi_debug().unwrap(),
f
)
}
}
}
impl<'lt,P,I,V> Display for RObject<'lt,P,I,V>
where
P: Deref<Target=()>+GetPointerKind,
I: InterfaceType<Display = Implemented<trait_marker::Display>>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe{
adapt_std_fmt::<ErasedObject>(
self.sabi_erased_ref(),
self.sabi_robject_vtable()._sabi_display().unwrap(),
f
)
}
}
}
impl<'lt,P, I,V> std::error::Error for RObject<'lt,P,I,V>
where
P: Deref<Target=()>+GetPointerKind,
I: InterfaceBound<
Display=Implemented<trait_marker::Display>,
Debug=Implemented<trait_marker::Debug>,
Error=Implemented<trait_marker::Error>,
>,
{}
unsafe impl<'lt,P,I,V> Send for RObject<'lt,P,I,V>
where
P:GetPointerKind,
I:InterfaceType<Send = Implemented<trait_marker::Send>>,
{}
unsafe impl<'lt,P,I,V> Sync for RObject<'lt,P,I,V>
where
P:GetPointerKind,
I:InterfaceType<Sync = Implemented<trait_marker::Sync>>,
{}
impl<'lt,P,I,V> RObject<'lt,P,I,V>
where
P:GetPointerKind<Target=()>,
{
pub unsafe fn with_vtable<OrigPtr>(
ptr:OrigPtr,
vtable:PrefixRef<V>,
)-> RObject<'lt,P,I,V>
where
OrigPtr:CanTransmuteElement<(),TransmutedPtr=P>,
OrigPtr::Target:Sized+'lt,
P:Deref<Target=()>,
{
RObject{
vtable,
ptr:ManuallyDrop::new( ptr.transmute_element::<()>() ),
_marker:PhantomData,
}
}
}
impl<'borr,'a,I,V> RObject<'borr,RRef<'a,()>,I,V>{
pub const unsafe fn with_vtable_const<T,Unerasability>(
ptr: &'a T,
vtable:VTableTO_RO<T,RRef<'a,T>,Unerasability,V>,
)-> Self
where
T:'borr,
{
RObject{
vtable: vtable.robject_vtable(),
ptr:{
let x=RRef::new(ptr).transmute_ref::<()>();
ManuallyDrop::new(x)
},
_marker:PhantomData,
}
}
}
impl<'lt,P,I,V> RObject<'lt,P,I,V>
where
P:GetPointerKind,
{
fn sabi_check_same_utypeid<T>(&self) -> Result<(), UneraseError<()>>
where
T:'static,
{
let expected_typeid=self.sabi_robject_vtable()._sabi_type_id().get();
let actual_typeid=UTypeId::new::<T>();
if expected_typeid == MaybeCmp::Just(actual_typeid) {
Ok(())
} else {
Err(UneraseError {
robject:(),
expected_typeid,
actual_typeid,
})
}
}
pub fn into_unerased<T>(self) -> Result<P::TransmutedPtr, UneraseError<Self>>
where
T:'static,
P: Deref<Target=()>+CanTransmuteElement<T>,
{
check_unerased!(self,self.sabi_check_same_utypeid::<T>());
unsafe {
let this=ManuallyDrop::new(self);
Ok(ptr::read(&*this.ptr).transmute_element::<T>())
}
}
pub fn as_unerased<T>(&self) -> Result<&T, UneraseError<&Self>>
where
T:'static,
P:Deref<Target=()>+CanTransmuteElement<T>,
{
check_unerased!(self,self.sabi_check_same_utypeid::<T>());
unsafe {
Ok(transmute_reference::<(),T>(&**self.ptr))
}
}
pub fn as_unerased_mut<T>(&mut self) -> Result<&mut T, UneraseError<&mut Self>>
where
T:'static,
P:DerefMut<Target=()>+CanTransmuteElement<T>,
{
check_unerased!(self,self.sabi_check_same_utypeid::<T>());
unsafe {
Ok(transmute_mut_reference::<(),T>(&mut **self.ptr))
}
}
#[inline]
pub unsafe fn unchecked_into_unerased<T>(self) -> P::TransmutedPtr
where
P: Deref<Target=()> + CanTransmuteElement<T>,
{
let this=ManuallyDrop::new(self);
ptr::read(&*this.ptr).transmute_element::<T>()
}
#[inline]
pub unsafe fn unchecked_as_unerased<T>(&self) -> &T
where
P:Deref<Target=()>,
{
transmute_reference::<(),T>(&**self.ptr)
}
#[inline]
pub unsafe fn unchecked_as_unerased_mut<T>(&mut self) -> &mut T
where
P:DerefMut<Target=()>,
{
transmute_mut_reference::<(),T>(&mut **self.ptr)
}
}
mod private_struct {
pub struct PrivStruct;
}
use self::private_struct::PrivStruct;
pub trait ReborrowBounds<SendNess,SyncNess>{}
impl ReborrowBounds<Unimplemented<trait_marker::Send>,Unimplemented<trait_marker::Sync>>
for PrivStruct
{}
impl ReborrowBounds<Implemented<trait_marker::Send>,Implemented<trait_marker::Sync>>
for PrivStruct
{}
impl<'lt,P,I,V> RObject<'lt,P,I,V>
where
P:GetPointerKind,
I:InterfaceType,
{
pub fn reborrow<'re>(&'re self)->RObject<'lt,&'re (),I,V>
where
P:Deref<Target=()>,
PrivStruct:ReborrowBounds<I::Send,I::Sync>,
{
RObject{
vtable:self.vtable,
ptr:ManuallyDrop::new(&**self.ptr),
_marker:PhantomData,
}
}
pub fn reborrow_mut<'re>(&'re mut self)->RObject<'lt,&'re mut (),I,V>
where
P:DerefMut<Target=()>,
PrivStruct:ReborrowBounds<I::Send,I::Sync>,
{
RObject {
vtable: self.vtable,
ptr: ManuallyDrop::new(&mut **self.ptr),
_marker:PhantomData,
}
}
}
impl<'lt,P,I,V> RObject<'lt,P,I,V>
where
P:GetPointerKind,
{
#[inline]
pub fn sabi_et_vtable(&self)->PrefixRef<V>{
self.vtable
}
#[inline]
pub fn sabi_robject_vtable(&self)->RObjectVtable_Ref<(),P,I>{
unsafe{
BaseVtable_Ref(self.vtable.cast::<BaseVtable_Prefix<(),P,I>>())
._sabi_vtable()
}
}
#[inline]
fn sabi_into_erased_ptr(self)->ManuallyDrop<P>{
let __this= ManuallyDrop::new(self);
unsafe{ ptr::read(&__this.ptr) }
}
#[inline]
pub fn sabi_erased_ref(&self)->&ErasedObject<()>
where
P: __DerefTrait<Target=()>
{
unsafe{&*((&**self.ptr) as *const () as *const ErasedObject<()>)}
}
#[inline]
pub fn sabi_erased_mut(&mut self)->&mut ErasedObject<()>
where
P: __DerefMutTrait<Target=()>
{
unsafe{&mut *((&mut **self.ptr) as *mut () as *mut ErasedObject<()>)}
}
pub fn sabi_as_rref(&self) -> RRef<'_, ()>
where
P: __DerefTrait<Target=()>
{
unsafe {
std::mem::transmute(&**self.ptr as *const _ as *const ())
}
}
pub fn sabi_as_rmut(&mut self) -> RMut<'_, ()>
where
P: __DerefMutTrait<Target=()>
{
unsafe {
std::mem::transmute(&mut **self.ptr as *mut _ as *mut ())
}
}
#[inline]
pub fn sabi_with_value<F,R>(self,f:F)->R
where
P: OwnedPointer<Target=()>,
F:FnOnce(MovePtr<'_,()>)->R,
{
OwnedPointer::with_move_ptr(self.sabi_into_erased_ptr(),f)
}
}
impl<P,I,V> Drop for RObject<'_,P,I,V>
where
P:GetPointerKind,
{
fn drop(&mut self){
if <P as GetPointerKind>::KIND==PointerKind::SmartPointer {
let destructor=self.sabi_robject_vtable()._sabi_drop();
unsafe{
destructor(&mut self.ptr);
}
}
}
}
#[derive(Copy, Clone)]
pub struct UneraseError<T> {
robject:T,
expected_typeid:MaybeCmp<UTypeId>,
actual_typeid:UTypeId,
}
impl<T> UneraseError<T>{
fn map<F,U>(self,f:F)->UneraseError<U>
where F:FnOnce(T)->U
{
UneraseError{
robject :f(self.robject),
expected_typeid:self.expected_typeid,
actual_typeid :self.actual_typeid,
}
}
#[must_use]
pub fn into_inner(self)->T{
self.robject
}
}
impl<D> fmt::Debug for UneraseError<D>{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("UneraseError")
.field("dyn_trait",&"<not shown>")
.field("expected_typeid",&self.expected_typeid)
.field("actual_typeid",&self.actual_typeid)
.finish()
}
}
impl<D> fmt::Display for UneraseError<D>{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
impl<D> ::std::error::Error for UneraseError<D> {}