1macro_rules! impl_fn {
2 (@recurse () ($($nm:ident : $ty:ident),*)) => {
3 impl_fn!(@impl_all ($($nm : $ty),*));
4 };
5 (@recurse ($hd_nm:ident : $hd_ty:ident $(, $tl_nm:ident : $tl_ty:ident)*) ($($nm:ident : $ty:ident),*)) => {
6 impl_fn!(@impl_all ($($nm : $ty),*));
7 impl_fn!(@recurse ($($tl_nm : $tl_ty),*) ($($nm : $ty,)* $hd_nm : $hd_ty));
8 };
9
10 (@impl_all ($($nm:ident : $ty:ident),*)) => {
11 impl_fn!(@impl_core ($($nm : $ty),*), fn($($ty),*) -> Ret, true, false, "Rust");
12 impl_fn!(@impl_core ($($nm : $ty),*), unsafe fn($($ty),*) -> Ret, false, false, "Rust");
13
14 impl_fn!(@impl_u_and_s ($($nm : $ty),*), "C");
16 impl_fn!(@impl_u_and_s ($($nm : $ty),*), "system");
17
18 #[cfg(target_arch = "x86")]
20 impl_fn!(@impl_u_and_s ($($nm : $ty),*), "cdecl");
21 #[cfg(target_arch = "x86")]
22 impl_fn!(@impl_u_and_s ($($nm : $ty),*), "stdcall");
23 #[cfg(target_arch = "x86")]
24 impl_fn!(@impl_u_and_s ($($nm : $ty),*), "fastcall");
25
26 #[cfg(all(target_arch = "x86_64", target_os = "windows"))]
28 impl_fn!(@impl_u_and_s ($($nm : $ty),*), "win64");
29
30 #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
32 impl_fn!(@impl_u_and_s ($($nm : $ty),*), "sysv64");
33
34 #[cfg(any(target_arch = "arm"))]
36 impl_fn!(@impl_u_and_s ($($nm : $ty),*), "aapcs");
37 };
38
39 (@impl_u_and_s ($($nm:ident : $ty:ident),*), $abi:expr) => {
40 impl_fn!(@impl_core ($($nm : $ty),*), extern $abi fn($($ty),*) -> Ret, true, true, $abi);
41 impl_fn!(@impl_core ($($nm : $ty),*), unsafe extern $abi fn($($ty),*) -> Ret, false, true, $abi);
42 };
43
44 (@impl_core ($($nm:ident : $ty:ident),*), $fn_type:ty, $is_safe:expr, $is_extern:expr, $call_conv:expr) => {
45 unsafe impl<Ret: 'static, $($ty: 'static),*> crate::FunctionPtr for $fn_type {
46 type Args = ($($ty,)*);
47 type Output = Ret;
48
49 const ARITY: ::core::primitive::usize = impl_fn!(@count ($($ty)*));
50 const SAFE: ::core::primitive::bool = $is_safe;
51 const EXTERN: ::core::primitive::bool = $is_extern;
52 const ABI: crate::Abi = crate::abi::parse_or_fail($call_conv);
53 }
54 };
55
56 (@count ()) => {
57 0
58 };
59 (@count ($hd:tt $($tl:tt)*)) => {
60 1 + impl_fn!(@count ($($tl)*))
61 };
62
63 ($($nm:ident : $ty:ident),*) => {
64 impl_fn!(@recurse ($($nm : $ty),*) ());
65 };
66}
67
68impl_fn! {
69 __arg_0: A, __arg_1: B, __arg_2: C, __arg_3: D, __arg_4: E, __arg_5: F, __arg_6: G,
70 __arg_7: H, __arg_8: I, __arg_9: J, __arg_10: K, __arg_11: L
71}