pub mod builder;
pub mod type_substitute;
#[doc(hidden)]
pub use any_ref_macro::_make_any_ref;
pub use builder::build;
use builder::AnyRefBuilder;
pub use stable_deref_trait::{CloneStableDeref, StableDeref};
use std::ops::Deref;
pub use type_substitute::*;
#[macro_export]
macro_rules! make_any_ref {
($($tt:tt)*) => {
$crate::_make_any_ref!{
$crate;$($tt)*
}
};
}
pub struct AnyRef<T: LifetimeDowncast + ?Sized, O: 'static> {
holder: <T as ReturnType<'static>>::Target,
owner: O,
}
impl<T, O> AnyRef<T, O>
where
T: LifetimeDowncast + ?Sized,
O: StableDeref + 'static,
{
#[inline]
pub fn new<F>(owner: O, func: F) -> AnyRef<T, O>
where
F: for<'a> FnOnce(&'a <O as Deref>::Target) -> <T as ReturnType<'a>>::Target,
{
let tar = unsafe { &*(&*owner as *const _) };
AnyRef {
holder: func(tar),
owner: owner,
}
}
#[inline]
pub fn map<T2, F>(self, func: F) -> AnyRef<T2, O>
where
T2: LifetimeDowncast + ?Sized,
F: for<'a> FnOnce(
<T as ReturnType<'a>>::Target,
&'a <O as Deref>::Target,
) -> <T2 as ReturnType<'a>>::Target,
{
let r = unsafe { &*(&*self.owner as *const _) };
AnyRef {
holder: func(self.holder, r),
owner: self.owner,
}
}
#[inline]
pub fn map_build<F, R>(self, func: F) -> R
where
O: CloneStableDeref,
F: for<'a> FnOnce(<T as ReturnType<'a>>::Target, AnyRefBuilder<'a, O>) -> R,
{
func(self.holder, AnyRefBuilder::new(self.owner))
}
#[inline(always)]
pub fn get<'a>(&'a self) -> &'a <T as ReturnType<'a>>::Target {
<T as LifetimeDowncast>::lifetime_downcast(&self.holder)
}
#[inline]
pub fn into_inner(self) -> O {
self.owner
}
}
impl<T, O> Clone for AnyRef<T, O>
where
T: LifetimeDowncast + ?Sized,
for<'a> <T as ReturnType<'a>>::Target: Clone,
O: CloneStableDeref + 'static,
{
#[inline]
fn clone(&self) -> Self {
AnyRef {
holder: self.holder.clone(),
owner: self.owner.clone(),
}
}
}
pub fn new_any_ref<T, O, F>(owner: O, func: F) -> AnyRef<T, O>
where
T: LifetimeDowncast + ?Sized,
O: StableDeref + 'static,
F: for<'a> FnOnce(&'a <O as Deref>::Target) -> <T as ReturnType<'a>>::Target,
{
let tar = unsafe { &*(&*owner as *const _) };
AnyRef {
holder: func(tar),
owner: owner,
}
}