1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use std::{
os::raw::c_int,
mem,
};
use crate::{
prelude::*,
ruby::VALUE,
};
pub unsafe trait MethodFn {
const ARITY: c_int;
fn raw_fn(self) -> unsafe extern "C" fn() -> VALUE;
}
macro_rules! impl_trait {
($($a:expr $(,$args:ty)*;)+) => { $(
impl_trait!(@fn $a, unsafe extern "C" fn(this: AnyObject $(,$args)*));
impl_trait!(@fn $a, extern "C" fn(this: AnyObject $(,$args)*));
)+ };
(@fn $a:expr, $($f:tt)+) => {
unsafe impl<O: Object> MethodFn for $($f)+ -> O {
const ARITY: c_int = $a;
#[inline]
fn raw_fn(self) -> unsafe extern "C" fn() -> VALUE {
unsafe { mem::transmute(self) }
}
}
};
}
impl_trait! {
-2, Array;
-1, c_int, *const AnyObject;
}
macro_rules! replace {
($_t:tt $sub:tt) => { $sub };
}
macro_rules! count {
($($t:tt)*) => { 0 $(+ replace!($t 1))* };
}
macro_rules! impl_trait_many {
() => {
impl_trait! { 0; }
};
(, $($t:tt)*) => {
impl_trait_many!($($t)*);
impl_trait! { 1 + count!($($t)*), AnyObject $(, replace!($t AnyObject))* ; }
};
}
impl_trait_many!(,,,,, ,,,,, ,,,,,);