• ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify


    首先要说说什么时候使用weakSelf和strongSelf。

    下面引用一篇博客《到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf》的内容:

    Objective C 的 Block 是一个很实用的语法,特别是与GCD结合使用,可以很方便地实现并发、异步任务。但是,如果使用不当,Block 也会引起一些循环引用问题(retain cycle)—— Block 会 retain ‘self’,而 ‘self‘ 又 retain 了 Block。因为在 ObjC 中,直接调用一个实例变量,会被编译器处理成 ‘self->theVar’,’self’ 是一个 strong 类型的变量,引用计数会加 1,于是,self retains queue, queue retains block,block retains self。

    解决 retain circle

    Apple 官方的建议是,传进 Block 之前,把 ‘self’ 转换成 weak automatic 的变量,这样在 Block 中就不会出现对 self 的强引用。如果在 Block 执行完成之前,self 被释放了,weakSelf 也会变为 nil。

    示例代码:

    1 __weak __typeof__(self) weakSelf = self;
    2     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    3     [weakSelf doSomething];
    4 });

    clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外:

    1 __weak __typeof__(self) weakSelf = self;
    2     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    3     [weakSelf doSomething];
    4     [weakSelf doOtherThing];
    5 });

    在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,于是,strongSelf 就派上用场了:

    1 __weak __typeof__(self) weakSelf = self;
    2     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    3     __strong __typeof(self) strongSelf = weakSelf;
    4     [strongSelf doSomething];
    5     [strongSelf doOtherThing];
    6 });

    __strong 确保在 Block 内,strongSelf 不会被释放。

    总结

    • 在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。
    • 如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。

    -------------------------------分割线---------------------------------------------

    以上内容知道了我们为什么要用weakSelf和strongSelf, 为了简单实用一般会定义成宏weakify和strongify,如下:

     1 #ifndef    weakify
     2 #if __has_feature(objc_arc)
     3 
     4 #define weakify( x ) 
     5 _Pragma("clang diagnostic push") 
     6 _Pragma("clang diagnostic ignored "-Wshadow"") 
     7 autoreleasepool{} __weak __typeof__(x) __weak_##x##__ = x; 
     8 _Pragma("clang diagnostic pop")
     9 
    10 #else
    11 
    12 #define weakify( x ) 
    13 _Pragma("clang diagnostic push") 
    14 _Pragma("clang diagnostic ignored "-Wshadow"") 
    15 autoreleasepool{} __block __typeof__(x) __block_##x##__ = x; 
    16 _Pragma("clang diagnostic pop")
    17 
    18 #endif
    19 #endif
    20 
    21 #ifndef    strongify
    22 #if __has_feature(objc_arc)
    23 
    24 #define strongify( x ) 
    25 _Pragma("clang diagnostic push") 
    26 _Pragma("clang diagnostic ignored "-Wshadow"") 
    27 try{} @finally{} __typeof__(x) x = __weak_##x##__; 
    28 _Pragma("clang diagnostic pop")
    29 
    30 #else
    31 
    32 #define strongify( x ) 
    33 _Pragma("clang diagnostic push") 
    34 _Pragma("clang diagnostic ignored "-Wshadow"") 
    35 try{} @finally{} __typeof__(x) x = __block_##x##__; 
    36 _Pragma("clang diagnostic pop")
    37 
    38 #endif
    39 #endif
    View Code

    使用过RAC的同学应该都知道@weakify和@strongify,这两个宏在RAC中是已经定义好的,可以直接用,属于比较牛逼的写法。这两个宏一定成对出现,先@weakify再@strongify.可以很好的管理Block内部对self的引用。可以一步步点开发现其实使用到了C语言中的组合运算符。

    1 @weakify(self);  
    2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    3      @strongify(self);
    4      [self doSomething];
    5      [self doOtherThing];
    6  });

    将其单独提出来如下:

      1 #if DEBUG
      2 #define rac_keywordify autoreleasepool {}
      3 #else
      4 #define rac_keywordify try {} @catch (...) {}
      5 #endif
      6 
      7 #define rac_weakify_(INDEX, CONTEXT, VAR) 
      8 CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
      9 
     10 #define rac_strongify_(INDEX, VAR) 
     11 __strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);
     12 
     13 #define weakify(...) 
     14 rac_keywordify 
     15 metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
     16 
     17 #define strongify(...) 
     18 rac_keywordify 
     19 _Pragma("clang diagnostic push") 
     20 _Pragma("clang diagnostic ignored "-Wshadow"") 
     21 metamacro_foreach(rac_strongify_,, __VA_ARGS__) 
     22 _Pragma("clang diagnostic pop")
     23 
     24 
     25 /**
     26  * Executes one or more expressions (which may have a void type, such as a call
     27  * to a function that returns no value) and always returns true.
     28  */
     29 #define metamacro_exprify(...) 
     30 ((__VA_ARGS__), true)
     31 
     32 /**
     33  * Returns a string representation of VALUE after full macro expansion.
     34  */
     35 #define metamacro_stringify(VALUE) 
     36 metamacro_stringify_(VALUE)
     37 
     38 /**
     39  * Returns A and B concatenated after full macro expansion.
     40  */
     41 #define metamacro_concat(A, B) 
     42 metamacro_concat_(A, B)
     43 
     44 /**
     45  * Returns the Nth variadic argument (starting from zero). At least
     46  * N + 1 variadic arguments must be given. N must be between zero and twenty,
     47  * inclusive.
     48  */
     49 #define metamacro_at(N, ...) 
     50 metamacro_concat(metamacro_at, N)(__VA_ARGS__)
     51 
     52 /**
     53  * Returns the number of arguments (up to twenty) provided to the macro. At
     54  * least one argument must be provided.
     55  *
     56  * Inspired by P99: http://p99.gforge.inria.fr
     57  */
     58 #define metamacro_argcount(...) 
     59 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)
     60 
     61 /**
     62  * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is
     63  * given. Only the index and current argument will thus be passed to MACRO.
     64  */
     65 #define metamacro_foreach(MACRO, SEP, ...) 
     66 metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__)
     67 
     68 /**
     69  * For each consecutive variadic argument (up to twenty), MACRO is passed the
     70  * zero-based index of the current argument, CONTEXT, and then the argument
     71  * itself. The results of adjoining invocations of MACRO are then separated by
     72  * SEP.
     73  *
     74  * Inspired by P99: http://p99.gforge.inria.fr
     75  */
     76 #define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) 
     77 metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
     78 
     79 /**
     80  * Identical to #metamacro_foreach_cxt. This can be used when the former would
     81  * fail due to recursive macro expansion.
     82  */
     83 #define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) 
     84 metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
     85 
     86 /**
     87  * In consecutive order, appends each variadic argument (up to twenty) onto
     88  * BASE. The resulting concatenations are then separated by SEP.
     89  *
     90  * This is primarily useful to manipulate a list of macro invocations into instead
     91  * invoking a different, possibly related macro.
     92  */
     93 #define metamacro_foreach_concat(BASE, SEP, ...) 
     94 metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__)
     95 
     96 /**
     97  * Iterates COUNT times, each time invoking MACRO with the current index
     98  * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO
     99  * are then separated by SEP.
    100  *
    101  * COUNT must be an integer between zero and twenty, inclusive.
    102  */
    103 #define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) 
    104 metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT)
    105 
    106 /**
    107  * Returns the first argument given. At least one argument must be provided.
    108  *
    109  * This is useful when implementing a variadic macro, where you may have only
    110  * one variadic argument, but no way to retrieve it (for example, because c ...
    111  * always needs to match at least one argument).
    112  *
    113  * @code
    114  
    115  #define varmacro(...) 
    116  metamacro_head(__VA_ARGS__)
    117  
    118  * @endcode
    119  */
    120 #define metamacro_head(...) 
    121 metamacro_head_(__VA_ARGS__, 0)
    122 
    123 /**
    124  * Returns every argument except the first. At least two arguments must be
    125  * provided.
    126  */
    127 #define metamacro_tail(...) 
    128 metamacro_tail_(__VA_ARGS__)
    129 
    130 /**
    131  * Returns the first N (up to twenty) variadic arguments as a new argument list.
    132  * At least N variadic arguments must be provided.
    133  */
    134 #define metamacro_take(N, ...) 
    135 metamacro_concat(metamacro_take, N)(__VA_ARGS__)
    136 
    137 /**
    138  * Removes the first N (up to twenty) variadic arguments from the given argument
    139  * list. At least N variadic arguments must be provided.
    140  */
    141 #define metamacro_drop(N, ...) 
    142 metamacro_concat(metamacro_drop, N)(__VA_ARGS__)
    143 
    144 /**
    145  * Decrements VAL, which must be a number between zero and twenty, inclusive.
    146  *
    147  * This is primarily useful when dealing with indexes and counts in
    148  * metaprogramming.
    149  */
    150 #define metamacro_dec(VAL) 
    151 metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
    152 
    153 /**
    154  * Increments VAL, which must be a number between zero and twenty, inclusive.
    155  *
    156  * This is primarily useful when dealing with indexes and counts in
    157  * metaprogramming.
    158  */
    159 #define metamacro_inc(VAL) 
    160 metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
    161 
    162 /**
    163  * If A is equal to B, the next argument list is expanded; otherwise, the
    164  * argument list after that is expanded. A and B must be numbers between zero
    165  * and twenty, inclusive. Additionally, B must be greater than or equal to A.
    166  *
    167  * @code
    168  
    169  // expands to true
    170  metamacro_if_eq(0, 0)(true)(false)
    171  
    172  // expands to false
    173  metamacro_if_eq(0, 1)(true)(false)
    174  
    175  * @endcode
    176  *
    177  * This is primarily useful when dealing with indexes and counts in
    178  * metaprogramming.
    179  */
    180 #define metamacro_if_eq(A, B) 
    181 metamacro_concat(metamacro_if_eq, A)(B)
    182 
    183 /**
    184  * Identical to #metamacro_if_eq. This can be used when the former would fail
    185  * due to recursive macro expansion.
    186  */
    187 #define metamacro_if_eq_recursive(A, B) 
    188 metamacro_concat(metamacro_if_eq_recursive, A)(B)
    189 
    190 /**
    191  * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and
    192  * twenty, inclusive.
    193  *
    194  * For the purposes of this test, zero is considered even.
    195  */
    196 #define metamacro_is_even(N) 
    197 metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
    198 
    199 /**
    200  * Returns the logical NOT of B, which must be the number zero or one.
    201  */
    202 #define metamacro_not(B) 
    203 metamacro_at(B, 1, 0)
    204 
    205 // IMPLEMENTATION DETAILS FOLLOW!
    206 // Do not write code that depends on anything below this line.
    207 #define metamacro_stringify_(VALUE) # VALUE
    208 #define metamacro_concat_(A, B) A ## B
    209 #define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)
    210 #define metamacro_head_(FIRST, ...) FIRST
    211 #define metamacro_tail_(FIRST, ...) __VA_ARGS__
    212 #define metamacro_consume_(...)
    213 #define metamacro_expand_(...) __VA_ARGS__
    214 
    215 // implemented from scratch so that metamacro_concat() doesn't end up nesting
    216 #define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG)
    217 #define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG
    218 
    219 // metamacro_at expansions
    220 #define metamacro_at0(...) metamacro_head(__VA_ARGS__)
    221 #define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__)
    222 #define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__)
    223 #define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__)
    224 #define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__)
    225 #define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__)
    226 #define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__)
    227 #define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__)
    228 #define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__)
    229 #define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__)
    230 #define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__)
    231 #define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__)
    232 #define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__)
    233 #define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__)
    234 #define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__)
    235 #define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__)
    236 #define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__)
    237 #define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__)
    238 #define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__)
    239 #define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__)
    240 #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__)
    241 
    242 // metamacro_foreach_cxt expansions
    243 #define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT)
    244 #define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
    245 
    246 #define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) 
    247 metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) 
    248 SEP 
    249 MACRO(1, CONTEXT, _1)
    250 
    251 #define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) 
    252 metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) 
    253 SEP 
    254 MACRO(2, CONTEXT, _2)
    255 
    256 #define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) 
    257 metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) 
    258 SEP 
    259 MACRO(3, CONTEXT, _3)
    260 
    261 #define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) 
    262 metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) 
    263 SEP 
    264 MACRO(4, CONTEXT, _4)
    265 
    266 #define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) 
    267 metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) 
    268 SEP 
    269 MACRO(5, CONTEXT, _5)
    270 
    271 #define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) 
    272 metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) 
    273 SEP 
    274 MACRO(6, CONTEXT, _6)
    275 
    276 #define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) 
    277 metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) 
    278 SEP 
    279 MACRO(7, CONTEXT, _7)
    280 
    281 #define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) 
    282 metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) 
    283 SEP 
    284 MACRO(8, CONTEXT, _8)
    285 
    286 #define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) 
    287 metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) 
    288 SEP 
    289 MACRO(9, CONTEXT, _9)
    290 
    291 #define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) 
    292 metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) 
    293 SEP 
    294 MACRO(10, CONTEXT, _10)
    295 
    296 #define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) 
    297 metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) 
    298 SEP 
    299 MACRO(11, CONTEXT, _11)
    300 
    301 #define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) 
    302 metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) 
    303 SEP 
    304 MACRO(12, CONTEXT, _12)
    305 
    306 #define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) 
    307 metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) 
    308 SEP 
    309 MACRO(13, CONTEXT, _13)
    310 
    311 #define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) 
    312 metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) 
    313 SEP 
    314 MACRO(14, CONTEXT, _14)
    315 
    316 #define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) 
    317 metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) 
    318 SEP 
    319 MACRO(15, CONTEXT, _15)
    320 
    321 #define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) 
    322 metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) 
    323 SEP 
    324 MACRO(16, CONTEXT, _16)
    325 
    326 #define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) 
    327 metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) 
    328 SEP 
    329 MACRO(17, CONTEXT, _17)
    330 
    331 #define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) 
    332 metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) 
    333 SEP 
    334 MACRO(18, CONTEXT, _18)
    335 
    336 #define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) 
    337 metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) 
    338 SEP 
    339 MACRO(19, CONTEXT, _19)
    340 
    341 // metamacro_foreach_cxt_recursive expansions
    342 #define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT)
    343 #define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
    344 
    345 #define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) 
    346 metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) 
    347 SEP 
    348 MACRO(1, CONTEXT, _1)
    349 
    350 #define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) 
    351 metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) 
    352 SEP 
    353 MACRO(2, CONTEXT, _2)
    354 
    355 #define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) 
    356 metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) 
    357 SEP 
    358 MACRO(3, CONTEXT, _3)
    359 
    360 #define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) 
    361 metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) 
    362 SEP 
    363 MACRO(4, CONTEXT, _4)
    364 
    365 #define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) 
    366 metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) 
    367 SEP 
    368 MACRO(5, CONTEXT, _5)
    369 
    370 #define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) 
    371 metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) 
    372 SEP 
    373 MACRO(6, CONTEXT, _6)
    374 
    375 #define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) 
    376 metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) 
    377 SEP 
    378 MACRO(7, CONTEXT, _7)
    379 
    380 #define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) 
    381 metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) 
    382 SEP 
    383 MACRO(8, CONTEXT, _8)
    384 
    385 #define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) 
    386 metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) 
    387 SEP 
    388 MACRO(9, CONTEXT, _9)
    389 
    390 #define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) 
    391 metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) 
    392 SEP 
    393 MACRO(10, CONTEXT, _10)
    394 
    395 #define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) 
    396 metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) 
    397 SEP 
    398 MACRO(11, CONTEXT, _11)
    399 
    400 #define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) 
    401 metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) 
    402 SEP 
    403 MACRO(12, CONTEXT, _12)
    404 
    405 #define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) 
    406 metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) 
    407 SEP 
    408 MACRO(13, CONTEXT, _13)
    409 
    410 #define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) 
    411 metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) 
    412 SEP 
    413 MACRO(14, CONTEXT, _14)
    414 
    415 #define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) 
    416 metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) 
    417 SEP 
    418 MACRO(15, CONTEXT, _15)
    419 
    420 #define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) 
    421 metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) 
    422 SEP 
    423 MACRO(16, CONTEXT, _16)
    424 
    425 #define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) 
    426 metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) 
    427 SEP 
    428 MACRO(17, CONTEXT, _17)
    429 
    430 #define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) 
    431 metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) 
    432 SEP 
    433 MACRO(18, CONTEXT, _18)
    434 
    435 #define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) 
    436 metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) 
    437 SEP 
    438 MACRO(19, CONTEXT, _19)
    439 
    440 // metamacro_for_cxt expansions
    441 #define metamacro_for_cxt0(MACRO, SEP, CONTEXT)
    442 #define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT)
    443 
    444 #define metamacro_for_cxt2(MACRO, SEP, CONTEXT) 
    445 metamacro_for_cxt1(MACRO, SEP, CONTEXT) 
    446 SEP 
    447 MACRO(1, CONTEXT)
    448 
    449 #define metamacro_for_cxt3(MACRO, SEP, CONTEXT) 
    450 metamacro_for_cxt2(MACRO, SEP, CONTEXT) 
    451 SEP 
    452 MACRO(2, CONTEXT)
    453 
    454 #define metamacro_for_cxt4(MACRO, SEP, CONTEXT) 
    455 metamacro_for_cxt3(MACRO, SEP, CONTEXT) 
    456 SEP 
    457 MACRO(3, CONTEXT)
    458 
    459 #define metamacro_for_cxt5(MACRO, SEP, CONTEXT) 
    460 metamacro_for_cxt4(MACRO, SEP, CONTEXT) 
    461 SEP 
    462 MACRO(4, CONTEXT)
    463 
    464 #define metamacro_for_cxt6(MACRO, SEP, CONTEXT) 
    465 metamacro_for_cxt5(MACRO, SEP, CONTEXT) 
    466 SEP 
    467 MACRO(5, CONTEXT)
    468 
    469 #define metamacro_for_cxt7(MACRO, SEP, CONTEXT) 
    470 metamacro_for_cxt6(MACRO, SEP, CONTEXT) 
    471 SEP 
    472 MACRO(6, CONTEXT)
    473 
    474 #define metamacro_for_cxt8(MACRO, SEP, CONTEXT) 
    475 metamacro_for_cxt7(MACRO, SEP, CONTEXT) 
    476 SEP 
    477 MACRO(7, CONTEXT)
    478 
    479 #define metamacro_for_cxt9(MACRO, SEP, CONTEXT) 
    480 metamacro_for_cxt8(MACRO, SEP, CONTEXT) 
    481 SEP 
    482 MACRO(8, CONTEXT)
    483 
    484 #define metamacro_for_cxt10(MACRO, SEP, CONTEXT) 
    485 metamacro_for_cxt9(MACRO, SEP, CONTEXT) 
    486 SEP 
    487 MACRO(9, CONTEXT)
    488 
    489 #define metamacro_for_cxt11(MACRO, SEP, CONTEXT) 
    490 metamacro_for_cxt10(MACRO, SEP, CONTEXT) 
    491 SEP 
    492 MACRO(10, CONTEXT)
    493 
    494 #define metamacro_for_cxt12(MACRO, SEP, CONTEXT) 
    495 metamacro_for_cxt11(MACRO, SEP, CONTEXT) 
    496 SEP 
    497 MACRO(11, CONTEXT)
    498 
    499 #define metamacro_for_cxt13(MACRO, SEP, CONTEXT) 
    500 metamacro_for_cxt12(MACRO, SEP, CONTEXT) 
    501 SEP 
    502 MACRO(12, CONTEXT)
    503 
    504 #define metamacro_for_cxt14(MACRO, SEP, CONTEXT) 
    505 metamacro_for_cxt13(MACRO, SEP, CONTEXT) 
    506 SEP 
    507 MACRO(13, CONTEXT)
    508 
    509 #define metamacro_for_cxt15(MACRO, SEP, CONTEXT) 
    510 metamacro_for_cxt14(MACRO, SEP, CONTEXT) 
    511 SEP 
    512 MACRO(14, CONTEXT)
    513 
    514 #define metamacro_for_cxt16(MACRO, SEP, CONTEXT) 
    515 metamacro_for_cxt15(MACRO, SEP, CONTEXT) 
    516 SEP 
    517 MACRO(15, CONTEXT)
    518 
    519 #define metamacro_for_cxt17(MACRO, SEP, CONTEXT) 
    520 metamacro_for_cxt16(MACRO, SEP, CONTEXT) 
    521 SEP 
    522 MACRO(16, CONTEXT)
    523 
    524 #define metamacro_for_cxt18(MACRO, SEP, CONTEXT) 
    525 metamacro_for_cxt17(MACRO, SEP, CONTEXT) 
    526 SEP 
    527 MACRO(17, CONTEXT)
    528 
    529 #define metamacro_for_cxt19(MACRO, SEP, CONTEXT) 
    530 metamacro_for_cxt18(MACRO, SEP, CONTEXT) 
    531 SEP 
    532 MACRO(18, CONTEXT)
    533 
    534 #define metamacro_for_cxt20(MACRO, SEP, CONTEXT) 
    535 metamacro_for_cxt19(MACRO, SEP, CONTEXT) 
    536 SEP 
    537 MACRO(19, CONTEXT)
    538 
    539 // metamacro_if_eq expansions
    540 #define metamacro_if_eq0(VALUE) 
    541 metamacro_concat(metamacro_if_eq0_, VALUE)
    542 
    543 #define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_
    544 #define metamacro_if_eq0_1(...) metamacro_expand_
    545 #define metamacro_if_eq0_2(...) metamacro_expand_
    546 #define metamacro_if_eq0_3(...) metamacro_expand_
    547 #define metamacro_if_eq0_4(...) metamacro_expand_
    548 #define metamacro_if_eq0_5(...) metamacro_expand_
    549 #define metamacro_if_eq0_6(...) metamacro_expand_
    550 #define metamacro_if_eq0_7(...) metamacro_expand_
    551 #define metamacro_if_eq0_8(...) metamacro_expand_
    552 #define metamacro_if_eq0_9(...) metamacro_expand_
    553 #define metamacro_if_eq0_10(...) metamacro_expand_
    554 #define metamacro_if_eq0_11(...) metamacro_expand_
    555 #define metamacro_if_eq0_12(...) metamacro_expand_
    556 #define metamacro_if_eq0_13(...) metamacro_expand_
    557 #define metamacro_if_eq0_14(...) metamacro_expand_
    558 #define metamacro_if_eq0_15(...) metamacro_expand_
    559 #define metamacro_if_eq0_16(...) metamacro_expand_
    560 #define metamacro_if_eq0_17(...) metamacro_expand_
    561 #define metamacro_if_eq0_18(...) metamacro_expand_
    562 #define metamacro_if_eq0_19(...) metamacro_expand_
    563 #define metamacro_if_eq0_20(...) metamacro_expand_
    564 
    565 #define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE))
    566 #define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE))
    567 #define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE))
    568 #define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE))
    569 #define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE))
    570 #define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE))
    571 #define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE))
    572 #define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE))
    573 #define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE))
    574 #define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE))
    575 #define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE))
    576 #define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE))
    577 #define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE))
    578 #define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE))
    579 #define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE))
    580 #define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE))
    581 #define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE))
    582 #define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE))
    583 #define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE))
    584 #define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE))
    585 
    586 // metamacro_if_eq_recursive expansions
    587 #define metamacro_if_eq_recursive0(VALUE) 
    588 metamacro_concat(metamacro_if_eq_recursive0_, VALUE)
    589 
    590 #define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_
    591 #define metamacro_if_eq_recursive0_1(...) metamacro_expand_
    592 #define metamacro_if_eq_recursive0_2(...) metamacro_expand_
    593 #define metamacro_if_eq_recursive0_3(...) metamacro_expand_
    594 #define metamacro_if_eq_recursive0_4(...) metamacro_expand_
    595 #define metamacro_if_eq_recursive0_5(...) metamacro_expand_
    596 #define metamacro_if_eq_recursive0_6(...) metamacro_expand_
    597 #define metamacro_if_eq_recursive0_7(...) metamacro_expand_
    598 #define metamacro_if_eq_recursive0_8(...) metamacro_expand_
    599 #define metamacro_if_eq_recursive0_9(...) metamacro_expand_
    600 #define metamacro_if_eq_recursive0_10(...) metamacro_expand_
    601 #define metamacro_if_eq_recursive0_11(...) metamacro_expand_
    602 #define metamacro_if_eq_recursive0_12(...) metamacro_expand_
    603 #define metamacro_if_eq_recursive0_13(...) metamacro_expand_
    604 #define metamacro_if_eq_recursive0_14(...) metamacro_expand_
    605 #define metamacro_if_eq_recursive0_15(...) metamacro_expand_
    606 #define metamacro_if_eq_recursive0_16(...) metamacro_expand_
    607 #define metamacro_if_eq_recursive0_17(...) metamacro_expand_
    608 #define metamacro_if_eq_recursive0_18(...) metamacro_expand_
    609 #define metamacro_if_eq_recursive0_19(...) metamacro_expand_
    610 #define metamacro_if_eq_recursive0_20(...) metamacro_expand_
    611 
    612 #define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE))
    613 #define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE))
    614 #define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE))
    615 #define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE))
    616 #define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE))
    617 #define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE))
    618 #define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE))
    619 #define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE))
    620 #define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE))
    621 #define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE))
    622 #define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE))
    623 #define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE))
    624 #define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE))
    625 #define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE))
    626 #define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE))
    627 #define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE))
    628 #define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE))
    629 #define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE))
    630 #define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE))
    631 #define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE))
    632 
    633 // metamacro_take expansions
    634 #define metamacro_take0(...)
    635 #define metamacro_take1(...) metamacro_head(__VA_ARGS__)
    636 #define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__))
    637 #define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__))
    638 #define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__))
    639 #define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__))
    640 #define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__))
    641 #define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__))
    642 #define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__))
    643 #define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__))
    644 #define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__))
    645 #define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__))
    646 #define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__))
    647 #define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__))
    648 #define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__))
    649 #define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__))
    650 #define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__))
    651 #define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__))
    652 #define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__))
    653 #define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__))
    654 #define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__))
    655 
    656 // metamacro_drop expansions
    657 #define metamacro_drop0(...) __VA_ARGS__
    658 #define metamacro_drop1(...) metamacro_tail(__VA_ARGS__)
    659 #define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__))
    660 #define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__))
    661 #define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__))
    662 #define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__))
    663 #define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__))
    664 #define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__))
    665 #define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__))
    666 #define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__))
    667 #define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__))
    668 #define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__))
    669 #define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__))
    670 #define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__))
    671 #define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__))
    672 #define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__))
    673 #define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__))
    674 #define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__))
    675 #define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__))
    676 #define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__))
    677 #define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__))
    View Code
  • 相关阅读:
    linux下的usb抓包方法【转】
    一个脚本和一个容易疏忽的问题strcmp、strncmp、memcmp的用法【原创】
    牛人博客网址
    linux设备驱动之USB主机控制器驱动分析 【转】
    Linux内核跟踪之syscall tracer 【转】
    Linux内核跟踪之trace框架分析【转】
    该怎样选择框架?
    git 解决冲突的办法
    volley源代码解析(七)--终于目的之Response<T>
    WebLogic(12C)——Server
  • 原文地址:https://www.cnblogs.com/wanyakun/p/5198492.html
Copyright © 2020-2023  润新知