use core::mem;
use crate::__macro_helpers::IdReturnValue;
use crate::encode::{EncodeArgument, EncodeArguments, EncodeReturn, RefEncode};
use crate::rc::Allocated;
use crate::runtime::{Imp, MessageReceiver, Sel};
use crate::Message;
mod private {
pub trait Sealed {}
}
pub trait MethodImplementation: private::Sealed + Sized {
type Callee: ?Sized + RefEncode;
type Arguments: EncodeArguments;
type Return: EncodeReturn;
#[doc(hidden)]
fn __imp(self) -> Imp;
}
macro_rules! method_impl_inner {
($(($unsafe:ident))? $abi:literal; $($t:ident),*) => {
impl<T, R, $($t),*> private::Sealed for $($unsafe)? extern $abi fn(T, Sel $(, $t)*) -> R
where
T: ?Sized + MessageReceiver,
R: EncodeReturn,
$($t: EncodeArgument,)*
{}
impl<T, R, $($t),*> MethodImplementation for $($unsafe)? extern $abi fn(T, Sel $(, $t)*) -> R
where
T: ?Sized + MessageReceiver,
R: EncodeReturn,
$($t: EncodeArgument,)*
{
type Callee = T::__Inner;
type Arguments = ($($t,)*);
type Return = R;
fn __imp(self) -> Imp {
unsafe { mem::transmute(self) }
}
}
impl<T, $($t),*> private::Sealed for $($unsafe)? extern $abi fn(Allocated<T>, Sel $(, $t)*) -> IdReturnValue
where
T: ?Sized + Message,
$($t: EncodeArgument,)*
{}
#[doc(hidden)]
impl<T, $($t),*> MethodImplementation for $($unsafe)? extern $abi fn(Allocated<T>, Sel $(, $t)*) -> IdReturnValue
where
T: ?Sized + Message,
$($t: EncodeArgument,)*
{
type Callee = T;
type Arguments = ($($t,)*);
type Return = IdReturnValue;
fn __imp(self) -> Imp {
unsafe { mem::transmute(self) }
}
}
};
}
macro_rules! method_impl {
($($t:ident),*) => {
method_impl_inner!((unsafe) "C"; $($t),*);
method_impl_inner!("C"; $($t),*);
#[cfg(feature = "unstable-c-unwind")]
method_impl_inner!((unsafe) "C-unwind"; $($t),*);
#[cfg(feature = "unstable-c-unwind")]
method_impl_inner!("C-unwind"; $($t),*);
};
}
method_impl!();
method_impl!(A);
method_impl!(A, B);
method_impl!(A, B, C);
method_impl!(A, B, C, D);
method_impl!(A, B, C, D, E);
method_impl!(A, B, C, D, E, F);
method_impl!(A, B, C, D, E, F, G);
method_impl!(A, B, C, D, E, F, G, H);
method_impl!(A, B, C, D, E, F, G, H, I);
method_impl!(A, B, C, D, E, F, G, H, I, J);
method_impl!(A, B, C, D, E, F, G, H, I, J, K);
method_impl!(A, B, C, D, E, F, G, H, I, J, K, L);
method_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M);
method_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
method_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
method_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);