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

 

posted @ 2016-02-18 16:06  坤坤同学  阅读(8808)  评论(2编辑  收藏  举报