#[allow(unused)]
use crate::{IntoMetaTuple, MetaAny, MetaItem, MetaTuple};
#[macro_export]
macro_rules! meta_tuple {
() => {()};
(@[$prev: expr]) => {
$prev
};
(@[$prev: expr] #$e: expr $(, $($rest: tt)*)?) => {
meta_tuple!(@[$crate::Join($prev, $e)] $($($rest)*)?)
};
(@[$prev: expr] &mut $e: expr $(, $($rest: tt)*)?) => {
meta_tuple!(@[$crate::Join($prev, $crate::MetaItem::from_mut(&mut $e))] $($($rest)*)?)
};
(@[$prev: expr] &$e: expr $(, $($rest: tt)*)?) => {
meta_tuple!(@[$crate::Join($prev, $crate::MetaItem::from_ref(&$e))] $($($rest)*)?)
};
(@[$prev: expr] $e: expr $(, $($rest: tt)*)?) => {
meta_tuple!(@[$crate::Join($prev, $crate::MetaItem($e))] $($($rest)*)?)
};
(#$e: expr $(, $($rest: tt)*)?) => {
meta_tuple!(@[$e] $($($rest)*)?)
};
(&mut $e: expr $(, $($rest: tt)*)?) => {
meta_tuple!(@[$crate::MetaItem::from_mut(&mut $e)] $($($rest)*)?)
};
(&$e: expr $(, $($rest: tt)*)?) => {
meta_tuple!(@[$crate::MetaItem::from_ref(&$e)] $($($rest)*)?)
};
($e: expr $(, $($rest: tt)*)?) => {
meta_tuple!(@[$crate::MetaItem($e)] $($($rest)*)?)
};
}
#[macro_export]
macro_rules! meta_tuple_type {
() => {()};
(@[$prev: ty]) => {
$prev
};
(@[$prev: ty] #$ty: ty $(, $($tt:tt)*)?) => {
$crate::meta_tuple_type!{@[$crate::Join<$prev, $ty>] $($($tt)*)?}
};
(@[$prev: ty] &mut $ty: ty $(, $($tt:tt)*)?) => {
$crate::meta_tuple_type!{@[$crate::Join<$prev, &mut $crate::MetaItem<$ty>>] $($($tt)*)?}
};
(@[$prev: ty] &$ty: ty $(, $($tt:tt)*)?) => {
$crate::meta_tuple_type!{@[$crate::Join<$prev, &$crate::MetaItem<$ty>>] $($($tt)*)?}
};
(@[$prev: ty] $ty: ty $(, $($tt:tt)*)?) => {
$crate::meta_tuple_type!{@[$crate::Join<$prev, $crate::MetaItem<$ty>>] $($($tt)*)?}
};
(#$ty: ty $(, $($tt:tt)*)?) => {
$crate::meta_tuple_type!{@[$ty] $($($tt)*)?}
};
(&mut $ty: ty $(, $($tt:tt)*)?) => {
$crate::meta_tuple_type!{@[&mut $crate::MetaItem<$ty>] $($($tt)*)?}
};
(&$ty: ty $(, $($tt:tt)*)?) => {
$crate::meta_tuple_type!{@[&$crate::MetaItem<$ty>] $($($tt)*)?}
};
($ty: ty $(, $($tt:tt)*)?) => {
$crate::meta_tuple_type!{@[$crate::MetaItem<$ty>] $($($tt)*)?}
};
}
#[macro_export]
macro_rules! impl_meta_any {
($trait: ident) => {
const _: () = {
use $crate::MetaAny;
impl dyn $trait + '_ {
pub fn get<T: 'static>(&self) -> Option<&T> {
if let Some(value) = (&() as &dyn $crate::Any).downcast_ref() {
return Some(value);
}
match self.as_erased() {
$crate::ErasedInner::None => None,
$crate::ErasedInner::Any(any) => any.downcast_ref(),
$crate::ErasedInner::Joined(a, b) => a.get().or_else(|| b.get()),
$crate::ErasedInner::Struct(s) => {
let mut idx = 0;
while let Some(field) = s.get_field(idx) {
if let Some(result) = field.downcast_ref() {
return Some(result);
}
idx += 1;
}
None
}
}
}
pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
if (&mut () as &mut dyn $crate::Any)
.downcast_mut::<T>()
.is_some()
{
return Some(unsafe { ::core::ptr::NonNull::dangling().as_mut() });
}
match self.as_erased_mut() {
$crate::ErasedInnerMut::None => None,
$crate::ErasedInnerMut::Any(any) => any.downcast_mut(),
$crate::ErasedInnerMut::Joined(a, b) => a.get_mut().or_else(|| b.get_mut()),
$crate::ErasedInnerMut::Struct(mut s) => {
let mut idx = 0;
$crate::polonius_loop! { |s| -> Option<&'polonius mut T> {
let Some(field) = s.get_field_mut(idx) else {
$crate::polonius_return!(None);
};
if let Some(result) = field.downcast_mut() {
$crate::polonius_return!(Some(result));
}
idx += 1;
}}
}
}
}
}
};
};
}
#[deprecated = "use impl_meta_any"]
#[macro_export]
macro_rules! impl_meta_box {
($($tt: tt)*) => {
$crate::impl_meta_any!($($tt)*)
}
}