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

来源:互联网 发布:网上考勤软件 编辑:程序博客网 时间:2024/06/11 09:34

http://www.cnblogs.com/wanyakun/p/5198492.html

首先要说说什么时候使用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 #else11 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 #endif19 #endif20 21 #ifndef    strongify22 #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 #else31 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 #endif39 #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 only110  * one variadic argument, but no way to retrieve it (for example, because \c ...111  * always needs to match at least one argument).112  *113  * @code114  115  #define varmacro(...) \116  metamacro_head(__VA_ARGS__)117  118  * @endcode119  */120 #define metamacro_head(...) \121 metamacro_head_(__VA_ARGS__, 0)122 123 /**124  * Returns every argument except the first. At least two arguments must be125  * 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 argument139  * 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 in148  * 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 in157  * 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, the164  * argument list after that is expanded. A and B must be numbers between zero165  * and twenty, inclusive. Additionally, B must be greater than or equal to A.166  *167  * @code168  169  // expands to true170  metamacro_if_eq(0, 0)(true)(false)171  172  // expands to false173  metamacro_if_eq(0, 1)(true)(false)174  175  * @endcode176  *177  * This is primarily useful when dealing with indexes and counts in178  * 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 fail185  * 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 and192  * 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) # VALUE208 #define metamacro_concat_(A, B) A ## B209 #define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)210 #define metamacro_head_(FIRST, ...) FIRST211 #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 nesting216 #define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG)217 #define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG218 219 // metamacro_at expansions220 #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 expansions243 #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 expansions342 #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 expansions441 #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 expansions540 #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 expansions587 #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 expansions634 #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 expansions657 #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__))
复制代码


0 0