#[macro_export]
macro_rules! declare_trait_object {
($type_alias:ident <$($generic:ident),* > = dyn $typedef:path
where
$($bound:tt)*
) =>
{
$crate::declare_trait_object_with_archived!($type_alias <$($generic),*> = dyn $typedef
{ type Archived = dyn $crate::dynamic::DeserializeDyn<$type_alias<$($generic),*>> }
where
$($bound)*
);
}
}
#[macro_export]
macro_rules! declare_trait_object_with_archived {
($type_alias:ident <$($generic:ident),* > = dyn $typedef:path
{ type Archived = dyn $archived_type:path }
where
$($bound:tt)*
) =>
{
pub type $type_alias<$($generic),*> = dyn $typedef;
$crate::derive_comparison_traits!($type_alias<$($generic),*> where $($bound)*);
$crate::derive_erase!(<$($generic),*> $typedef
{ type Archived = dyn $archived_type }
where $($bound)*);
impl<$($generic),*> $crate::dynamic::DowncastTrait for $type_alias<$($generic),*>
where
$($bound)*
{
}
impl<$($generic),*> std::hash::Hash for $type_alias<$($generic),*>
where
$($bound)*
{
fn hash<H>(&self, state: &mut H)
where H: std::hash::Hasher {
self.dyn_hash(state)
}
}
impl<$($generic),*> Clone for Box<$type_alias<$($generic),*>>
where
$($bound)*
{
fn clone(&self) -> Self {
dyn_clone::clone_box(self.as_ref())
}
}
impl<$($generic),*> rkyv::Deserialize<Box<$type_alias<$($generic),*>>, $crate::trace::Deserializer> for () {
fn deserialize(
&self,
_deserializer: &mut $crate::trace::Deserializer,
) -> Result<Box<$type_alias<$($generic),*>>, <$crate::trace::Deserializer as rkyv::Fallible>::Error> {
todo!("deserialize {}", std::any::type_name::<Self>())
}
}
impl<$($generic),*> rkyv::Archive for Box<$type_alias<$($generic),*>> {
type Archived = ();
type Resolver = ();
unsafe fn resolve(&self, _pos: usize, _resolver: Self::Resolver, _out: *mut Self::Archived) {
todo!()
}
}
impl<$($generic),*> rkyv::Serialize<$crate::trace::DbspSerializer<'_>> for Box<$type_alias<$($generic),*>> {
fn serialize(
&self,
_serializer: &mut $crate::trace::DbspSerializer,
) -> Result<Self::Resolver, <$crate::trace::DbspSerializer<'_> as rkyv::Fallible>::Error> {
todo!()
}
}
impl<$($generic),*> $crate::dynamic::ArchiveTrait for $type_alias<$($generic),*>
where
$($bound)*
{
type Archived = dyn $archived_type;
}
};
}
#[macro_export]
macro_rules! declare_typed_trait_object {
($type_alias:ident <$($generic:ident),* > = dyn $typedef:ty
[$inner_type:ty]
where
$($bound:tt)*
) =>
{
$crate::declare_trait_object!($type_alias<$($generic),*> = dyn $typedef where $($bound)*);
impl<$($generic),*> std::ops::Deref for $type_alias<$($generic),*>
where
$($bound)*
{
type Target = $inner_type;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const _ as *const Self::Target) }
}
}
impl<$($generic),*> std::ops::DerefMut for $type_alias<$($generic),*>
where
$($bound)*
{
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(self as *mut _ as *mut $inner_type) }
}
}
};
}
#[cfg(test)]
mod test {
use feldera_macros::IsNone;
use rkyv::{Archive, Deserialize, Serialize};
use size_of::SizeOf;
use crate::{
DBData, DBWeight,
dynamic::{Data, DataTrait, DataTraitTyped, Erase, WeightTrait, WeightTraitTyped},
};
#[derive(
Clone,
Default,
Debug,
PartialOrd,
Ord,
PartialEq,
Eq,
Hash,
SizeOf,
Archive,
Serialize,
Deserialize,
IsNone,
)]
#[archive_attr(derive(Ord, Eq, PartialEq, PartialOrd))]
#[archive(compare(PartialEq, PartialOrd))]
struct Foo<T1: DBData, T2: DBData> {
x: T1,
y: T2,
}
pub trait Bar<T1: DataTrait + ?Sized, T2: WeightTrait + ?Sized>: Data {
fn f1(&self) -> &T1;
fn f2(&self) -> &T2;
}
impl<T1: DataTraitTyped + ?Sized, T2: WeightTraitTyped + ?Sized> Bar<T1, T2>
for Foo<T1::Type, T2::Type>
where
T1::Type: DBData + Erase<T1>,
T2::Type: DBWeight + Erase<T2>,
{
fn f1(&self) -> &T1 {
self.x.erase()
}
fn f2(&self) -> &T2 {
self.y.erase()
}
}
declare_trait_object!(DynBar<T1, T2> = dyn Bar<T1, T2>
where
T1: DataTrait + ?Sized,
T2: WeightTrait + ?Sized
);
#[test]
fn declare_trait_object_test() {}
}