blob: b9a821a5e19cf8d7863f62ce4681463b18cc8fcd [file] [log] [blame]
bungeman@google.comf8d1aee2012-02-02 19:15:21 +00001/*
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