首先要说说什么时候使用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。
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 不会被释放。
-------------------------------分割线---------------------------------------------
以上内容知道了我们为什么要用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
使用过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__))