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