RAC中有一个宏定义metamacro_argcount(...) 其作用是计算出可变参中的数量,比如:int num = metamacro_argcount(a, b, c); 则相当于int num = 3; 因为采用的是宏展开,所以编译时就知道这个num的值了,无须等到运行时。作者说他的灵感 来于P99:Inspired by P99: http://p99.gforge.inria.fr
我们来剖析一下:
#define metamacro_argcount(...)
metamacro_at(20, VA_ARGS, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
宏metamacro_argcount的意义是计算出可变参的长度,通过这个宏可以在预处理之后就拿到可变参数的个数,而不是使用传统的va_start va_arg va_end这些运行时才可以确定可变参数信息的函数。
int count = metamacro_argcount(a, b, c);
NSLog(@"%d", count); // 3
#define metamacro_argcount(...) \
metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
展开为:int count = metamacro_at(20, a, b, c, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define metamacro_at(N, ...) \
metamacro_concat(metamacro_at, N)(__VA_ARGS__)
展开为:int count = metamacro_concat(metamacro_at, 20)(a, b, c, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define metamacro_concat(A, B) \
metamacro_concat_(A, B)
展开为:int count = metamacro_concat_(metamacro_at, 20)(a, b, c, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define metamacro_concat_(A, B) A ## B
展开为:int count = metamacro_at20(a, b, c, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__)
展开为:int count = metamacro_head(3, 2, 1)
#define metamacro_head(...) \
metamacro_head_(__VA_ARGS__, 0)
展开为:int count = metamacro_head_(3, 2, 1, 0)
#define metamacro_head_(FIRST, ...) FIRST
展开为:int count = 3
屌爆了!