#[macro_export]
macro_rules! interface {
{
$(
$vs:vis trait $iname:ident $(impl for $($implt:ty),* )? {
$(
$(extern $($abi:literal)?)? fn $fname:ident( $($arg_name:ident: $arg_ty:ty),* )
$(-> $ret:ty)? = $sep:tt $idx:expr $(, $mod_name:literal)?;
)*
}
)*
} => {
$(
#[allow(clippy::missing_safety_doc)]
$vs unsafe trait $iname: Sized {
const INDEX_OFFSET: usize = 0;
const FUNCTION_COUNT: usize = $( $crate::__count_fns!($fname) + )*0;
$(
$crate::__gen_func! {
$sep
[$($mod_name)? | $idx],
$(extern $($abi)?)?,
$fname,
($($arg_name, $arg_ty),* ),
$($ret)?
}
)*
}
$(
$(
unsafe impl $iname for $implt { }
)*
)?
)*
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __gen_func {
(# [| $idx:expr], $(extern $($abi:literal)?)?, $fname:ident, ( $($arg_name:ident, $arg_ty:ty),* ), $($ret:ty)? ) => {
$(extern $($abi)?)? fn $fname<'this>(&'this self, $($arg_name: $arg_ty),* ) $(-> $ret)? {
unsafe {
type Fn<'this> = $(extern $($abi)?)? fn(*const (), $($arg_ty),*) $(-> $ret)?;
#[allow(clippy::useless_transmute)]
((**core::mem::transmute::<_, *const *const [Fn<'this>; $idx + 1]>(self))[Self::INDEX_OFFSET + $idx])(
self as *const Self as _,
$($arg_name),*
)
}
}
};
(% [$mod_name:literal | $pattern:expr], $(extern $($abi:literal)?)?, $fname:ident, ( $($arg_name:ident, $arg_ty:ty),* ), $($ret:ty)? ) => {
$(extern $($abi)?)? fn $fname<'this>(&'this self, $($arg_name: $arg_ty),* ) $(-> $ret)? {
unsafe {
type Fn = $(extern $($abi)?)? fn(*const (), $($arg_ty),*) $(-> $ret)?;
$crate::function! {
$(extern $($abi)?)? fn __CALLE(usize, $($arg_ty),*) $(-> $ret)? = $mod_name%$pattern;
}
__CALLE(self as *const Self as usize, $($arg_name),*)
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __count_fns {
($a:ident) => {
1
};
}