RAC宏分析7:metamacro_if_eq
2017-07-05 本文已影响107人
大刘
metamacro_if_eq(A, B)(true)(false)
意思是如果A==B,执行true代码,否则执行false代码
比如:
#define RAC(TARGET, ...) \
metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__)) \
(RAC_(TARGET, __VA_ARGS__, nil)) \
(RAC_(TARGET, __VA_ARGS__))
意思是如果可变参个数==1,执行(RAC_(TARGET, __VA_ARGS__, nil)),否则执行(RAC_(TARGET, __VA_ARGS__))
来看宏定义:metamacro_if_eq
/**
* If A is equal to B, the next argument list is expanded; otherwise, the
* argument list after that is expanded. A and B must be numbers between zero
* and twenty, inclusive. Additionally, B must be greater than or equal to A.
*
* @code
// expands to true
metamacro_if_eq(0, 0)(true)(false)
// expands to false
metamacro_if_eq(0, 1)(true)(false)
* @endcode
*
* This is primarily useful when dealing with indexes and counts in
* metaprogramming.
*/
#define metamacro_if_eq(A, B) \
metamacro_concat(metamacro_if_eq, A)(B)
前提:A 和 B的值域都为[0,20],并且B要大于等于A,即0<=A<=B<=20。
展开为:
metamacro_concat(metamacro_if_eq, A)(B) -> metamacro_if_eqA(B)
再来看其宏定义:
#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE))
#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE))
#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE))
#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE))
#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE))
#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE))
#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE))
#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE))
#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE))
#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE))
#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE))
#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE))
#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE))
#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE))
#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE))
#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE))
#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE))
#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE))
#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE))
#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE))
这是一个递推的式子,最终会得到metamacro_if_eq0, 结果是:metamacro_if_eq0(B - A)
// metamacro_if_eq expansions
#define metamacro_if_eq0(VALUE) \
metamacro_concat(metamacro_if_eq0_, VALUE)
展开为:
metamacro_if_equ0_(B-A)
再通过下面的查表:
#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_
#define metamacro_if_eq0_1(...) metamacro_expand_
#define metamacro_if_eq0_2(...) metamacro_expand_
#define metamacro_if_eq0_3(...) metamacro_expand_
#define metamacro_if_eq0_4(...) metamacro_expand_
#define metamacro_if_eq0_5(...) metamacro_expand_
#define metamacro_if_eq0_6(...) metamacro_expand_
#define metamacro_if_eq0_7(...) metamacro_expand_
#define metamacro_if_eq0_8(...) metamacro_expand_
#define metamacro_if_eq0_9(...) metamacro_expand_
#define metamacro_if_eq0_10(...) metamacro_expand_
#define metamacro_if_eq0_11(...) metamacro_expand_
#define metamacro_if_eq0_12(...) metamacro_expand_
#define metamacro_if_eq0_13(...) metamacro_expand_
#define metamacro_if_eq0_14(...) metamacro_expand_
#define metamacro_if_eq0_15(...) metamacro_expand_
#define metamacro_if_eq0_16(...) metamacro_expand_
#define metamacro_if_eq0_17(...) metamacro_expand_
#define metamacro_if_eq0_18(...) metamacro_expand_
#define metamacro_if_eq0_19(...) metamacro_expand_
#define metamacro_if_eq0_20(...) metamacro_expand_
#define metamacro_consume_(...)
#define metamacro_expand_(...) __VA_ARGS__
除了0_0以外,其他所有操作都是直接透传参数,什么也不处理。metamacro_consume_(...)就是直接吞掉后续的参数。expand就是指的是可以继续展开宏,consume就是指的是终止展开宏,并吃掉后面的参数。
举2个例子
// 第一个例子
metamacro_if_eq(0, 0)(true)(false)
// 第二个例子
metamacro_if_eq(0, 1)(true)(false)
直接套用最终展开式:
// 第一个例子
metamacro_if_eq0_0(true)(false)
// 第二个例子
metamacro_if_eq0_1(true)(false)
继续展开:
// 第一个例子
true metamacro_consume_(false) => true
// 第二个例子
metamacro_expand_(false) => false
这个如果 B < A,那么(B - A) < 0,那么最终展开的式子就变成下面的样子:
metamacro_if_eq0_(负数)
这个宏展开到这个程度就没法继续下去了,就会出现编译错误。所以使用这个宏时要确保B>=A
最后来张图:
1.png
2.png