bungeman@google.com | f8d1aee | 2012-02-02 19:15:21 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2012 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #ifndef SkPreprocessorSeq_DEFINED |
| 9 | #define SkPreprocessorSeq_DEFINED |
| 10 | |
| 11 | #define SK_CONCAT(a, b) SK_CONCAT_I(a, b) // allow for macro expansion |
| 12 | #define SK_CONCAT_I(a, b) a ## b |
| 13 | |
| 14 | //A preprocessor pair is of the form '(a, b)' |
| 15 | #define SK_PAIR_FIRST(pair) SK_PAIR_FIRST_I pair |
| 16 | #define SK_PAIR_FIRST_I(a, b) a |
| 17 | #define SK_PAIR_SECOND(pair) SK_PAIR_SECOND_I pair |
| 18 | #define SK_PAIR_SECOND_I(a, b) b |
| 19 | |
| 20 | //A preprocessor sequence is of the form (a)(b)(c)SK_SEQ_END |
| 21 | #if 0 |
| 22 | //The following is what we logically want to do. |
| 23 | //However, MSVC expands macros at the wrong time, causing an error on use of |
| 24 | //SK_SEQ_IGNORE_SECOND_I because it formally takes two parameters, but we only |
| 25 | //pass "one" parameter in SK_SEQ_IGNORE_SECOND. |
| 26 | |
| 27 | #define SK_SEQ_HEAD(seq) SK_SEQ_IGNORE_SECOND(SK_SEQ_FIRST seq) |
| 28 | #define SK_SEQ_IGNORE_SECOND(x) SK_SEQ_IGNORE_SECOND_I(x) // expand x |
| 29 | #define SK_SEQ_IGNORE_SECOND_I(x, _) x |
| 30 | #define SK_SEQ_FIRST(x) x, SK_NIL |
| 31 | |
| 32 | #else |
| 33 | |
| 34 | //This is less obvious, but works on GCC, clang, and MSVC. |
| 35 | #define SK_SEQ_HEAD(seq) SK_SEQ_HEAD_II((SK_SEQ_FIRST seq)) |
| 36 | #define SK_SEQ_HEAD_II(x) SK_SEQ_IGNORE_SECOND_I x |
| 37 | #define SK_SEQ_IGNORE_SECOND_I(x, _) x |
| 38 | #define SK_SEQ_FIRST(x) x, SK_NIL |
| 39 | |
| 40 | #endif |
| 41 | |
| 42 | #define SK_SEQ_TAIL(seq) SK_SEQ_TAIL_I seq |
| 43 | #define SK_SEQ_TAIL_I(x) |
| 44 | |
| 45 | #define SK_SEQ_SIZE(seq) SK_CONCAT(SK_SEQ_SIZE_, SK_SEQ_SIZE_TERMINATOR seq) |
| 46 | |
| 47 | #define SK_SEQ_SIZE_TERMINATOR(_) SK_SEQ_SIZE_0 |
| 48 | #define SK_SEQ_SIZE_0(_) SK_SEQ_SIZE_1 |
| 49 | #define SK_SEQ_SIZE_1(_) SK_SEQ_SIZE_2 |
| 50 | #define SK_SEQ_SIZE_2(_) SK_SEQ_SIZE_3 |
| 51 | #define SK_SEQ_SIZE_3(_) SK_SEQ_SIZE_4 |
| 52 | #define SK_SEQ_SIZE_4(_) SK_SEQ_SIZE_5 |
| 53 | #define SK_SEQ_SIZE_5(_) SK_SEQ_SIZE_6 |
| 54 | #define SK_SEQ_SIZE_6(_) SK_SEQ_SIZE_7 |
| 55 | #define SK_SEQ_SIZE_7(_) SK_SEQ_SIZE_8 |
| 56 | #define SK_SEQ_SIZE_8(_) SK_SEQ_SIZE_9 |
| 57 | #define SK_SEQ_SIZE_9(_) SK_SEQ_SIZE_10 |
| 58 | #define SK_SEQ_SIZE_10(_) SK_SEQ_SIZE_11 |
| 59 | #define SK_SEQ_SIZE_11(_) SK_SEQ_SIZE_12 |
| 60 | #define SK_SEQ_SIZE_12(_) SK_SEQ_SIZE_13 |
| 61 | #define SK_SEQ_SIZE_13(_) SK_SEQ_SIZE_14 |
| 62 | #define SK_SEQ_SIZE_14(_) SK_SEQ_SIZE_15 |
| 63 | #define SK_SEQ_SIZE_15(_) SK_SEQ_SIZE_16 |
| 64 | #define SK_SEQ_SIZE_16(_) SK_SEQ_SIZE_17 |
| 65 | |
| 66 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_0 0 |
| 67 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_1 1 |
| 68 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_2 2 |
| 69 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_3 3 |
| 70 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_4 4 |
| 71 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_5 5 |
| 72 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_6 6 |
| 73 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_7 7 |
| 74 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_8 8 |
| 75 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_9 9 |
| 76 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_10 10 |
| 77 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_11 11 |
| 78 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_12 12 |
| 79 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_13 13 |
| 80 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_14 14 |
| 81 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_15 15 |
| 82 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_16 16 |
| 83 | #define SK_SEQ_SIZE_SK_SEQ_SIZE_17 17 |
| 84 | |
| 85 | #define SK_SEQ_FOREACH(op, data, seq) SK_SEQ_FOREACH_L(op, op, data, seq) |
| 86 | #define SK_SEQ_FOREACH_L(op, lop, data, seq) SK_CONCAT(SK_SEQ_FOREACH_, SK_SEQ_SIZE(seq)) (op, lop, data, SK_SEQ_HEAD(seq), SK_SEQ_TAIL(seq)) |
| 87 | |
| 88 | #define SK_SEQ_FOREACH_0(op,lop,d,x,t) |
| 89 | #define SK_SEQ_FOREACH_1(op,lop,d,x,t) lop(d,x) |
| 90 | #define SK_SEQ_FOREACH_2(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_1(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 91 | #define SK_SEQ_FOREACH_3(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_2(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 92 | #define SK_SEQ_FOREACH_4(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_3(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 93 | #define SK_SEQ_FOREACH_5(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_4(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 94 | #define SK_SEQ_FOREACH_6(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_5(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 95 | #define SK_SEQ_FOREACH_7(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_6(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 96 | #define SK_SEQ_FOREACH_8(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_7(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 97 | #define SK_SEQ_FOREACH_9(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_8(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 98 | #define SK_SEQ_FOREACH_10(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_9(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 99 | #define SK_SEQ_FOREACH_11(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_10(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 100 | #define SK_SEQ_FOREACH_12(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_11(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 101 | #define SK_SEQ_FOREACH_13(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_12(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 102 | #define SK_SEQ_FOREACH_14(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_13(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 103 | #define SK_SEQ_FOREACH_15(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_14(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 104 | #define SK_SEQ_FOREACH_16(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_15(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 105 | #define SK_SEQ_FOREACH_17(op,lop,d,x,t) op(d,x) SK_SEQ_FOREACH_16(op, lop, d, SK_SEQ_HEAD(t), SK_SEQ_TAIL(t)) |
| 106 | |
| 107 | #define SK_SEQ_END (SK_NIL) |
| 108 | |
| 109 | #endif |