大刘的 iOS 自学笔记

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
上一篇下一篇

猜你喜欢

热点阅读