]> git.ozlabs.org Git - ccan/blob - ccan/cppmagic/cppmagic.h
tal: allow notifiers on NULL.
[ccan] / ccan / cppmagic / cppmagic.h
1 /* MIT (BSD) license - see LICENSE file for details */
2 #ifndef CCAN_CPPMAGIC_H
3 #define CCAN_CPPMAGIC_H
4
5 /**
6  * CPPMAGIC_NOTHING - expands to nothing
7  */
8 #define CPPMAGIC_NOTHING()
9
10 /**
11  * CPPMAGIC_STRINGIFY - convert arguments to a string literal
12  */
13 #define _CPPMAGIC_STRINGIFY(...)        #__VA_ARGS__
14 #define CPPMAGIC_STRINGIFY(...)         _CPPMAGIC_STRINGIFY(__VA_ARGS__)
15
16 /**
17  * CPPMAGIC_GLUE2 - glue arguments together
18  *
19  * CPPMAGIC_GLUE2(@a_, @b_)
20  *      expands to the expansion of @a_ followed immediately
21  *      (combining tokens) by the expansion of @b_
22  */
23 #define _CPPMAGIC_GLUE2(a_, b_)         a_##b_
24 #define CPPMAGIC_GLUE2(a_, b_)          _CPPMAGIC_GLUE2(a_, b_)
25
26 /**
27  * CPPMAGIC_1ST - return 1st argument
28  *
29  * CPPMAGIC_1ST(@a_, ...)
30  *      expands to the expansion of @a_
31  */
32 #define CPPMAGIC_1ST(a_, ...)           a_
33
34 /**
35  * CPPMAGIC_2ND - return 2nd argument
36  *
37  * CPPMAGIC_2ST(@a_, @b_, ...)
38  *      expands to the expansion of @b_
39  */
40 #define CPPMAGIC_2ND(a_, b_, ...)       b_
41
42 /**
43  * CPPMAGIC_ISZERO - is argument '0'
44  *
45  * CPPMAGIC_ISZERO(@a)
46  *      expands to '1' if @a is '0', otherwise expands to '0'.
47  */
48 #define _CPPMAGIC_ISPROBE(...)          CPPMAGIC_2ND(__VA_ARGS__, 0)
49 #define _CPPMAGIC_PROBE()               $, 1
50 #define _CPPMAGIC_ISZERO_0              _CPPMAGIC_PROBE()
51 #define CPPMAGIC_ISZERO(a_)             \
52         _CPPMAGIC_ISPROBE(CPPMAGIC_GLUE2(_CPPMAGIC_ISZERO_, a_))
53
54 /**
55  * CPPMAGIC_NONZERO - is argument not '0'
56  *
57  * CPPMAGIC_NONZERO(@a)
58  *      expands to '0' if @a is '0', otherwise expands to '1'.
59  */
60 #define CPPMAGIC_NONZERO(a_)            CPPMAGIC_ISZERO(CPPMAGIC_ISZERO(a_))
61
62 /**
63  * CPPMAGIC_NONEMPTY - does the macro have any arguments?
64  *
65  * CPPMAGIC_NONEMPTY()
66  *      expands to '0'
67  * CPPMAGIC_NONEMPTY(@a)
68  * CPPMAGIC_NONEMPTY(@a, ...)
69  *      expand to '1'
70  */
71 #define _CPPMAGIC_EOA()                 0
72 #define CPPMAGIC_NONEMPTY(...)          \
73         CPPMAGIC_NONZERO(CPPMAGIC_1ST(_CPPMAGIC_EOA __VA_ARGS__)())
74
75 /**
76  * CPPMAGIC_ISEMPTY - does the macro have no arguments?
77  *
78  * CPPMAGIC_ISEMPTY()
79  *      expands to '1'
80  * CPPMAGIC_ISEMPTY(@a)
81  * CPPMAGIC_ISEMPTY(@a, ...)
82  *      expand to '0'
83  */
84 #define CPPMAGIC_ISEMPTY(...)           \
85         CPPMAGIC_ISZERO(CPPMAGIC_NONEMPTY(__VA_ARGS__))
86
87 /*
88  * CPPMAGIC_IFELSE - preprocessor conditional
89  *
90  * CPPMAGIC_IFELSE(@cond)(@if)(@else)
91  *      expands to @else if @cond is '0', otherwise expands to @if
92  */
93 #define _CPPMAGIC_IF_0(...)             _CPPMAGIC_IF_0_ELSE
94 #define _CPPMAGIC_IF_1(...)             __VA_ARGS__ _CPPMAGIC_IF_1_ELSE
95 #define _CPPMAGIC_IF_0_ELSE(...)        __VA_ARGS__
96 #define _CPPMAGIC_IF_1_ELSE(...)
97 #define _CPPMAGIC_IFELSE(cond_)         CPPMAGIC_GLUE2(_CPPMAGIC_IF_, cond_)
98 #define CPPMAGIC_IFELSE(cond_)          \
99         _CPPMAGIC_IFELSE(CPPMAGIC_NONZERO(cond_))
100
101 /**
102  * CPPMAGIC_EVAL - force multiple expansion passes
103  *
104  * Forces macros in the arguments to be expanded repeatedly (up to
105  * 1024 times) even when CPP would usually stop expanding.
106  */
107 #define CPPMAGIC_EVAL1(...)             __VA_ARGS__
108 #define CPPMAGIC_EVAL2(...)             \
109         CPPMAGIC_EVAL1(CPPMAGIC_EVAL1(__VA_ARGS__))
110 #define CPPMAGIC_EVAL4(...)             \
111         CPPMAGIC_EVAL2(CPPMAGIC_EVAL2(__VA_ARGS__))
112 #define CPPMAGIC_EVAL8(...)             \
113         CPPMAGIC_EVAL4(CPPMAGIC_EVAL4(__VA_ARGS__))
114 #define CPPMAGIC_EVAL16(...)            \
115         CPPMAGIC_EVAL8(CPPMAGIC_EVAL8(__VA_ARGS__))
116 #define CPPMAGIC_EVAL32(...)            \
117         CPPMAGIC_EVAL16(CPPMAGIC_EVAL16(__VA_ARGS__))
118 #define CPPMAGIC_EVAL64(...)            \
119         CPPMAGIC_EVAL32(CPPMAGIC_EVAL32(__VA_ARGS__))
120 #define CPPMAGIC_EVAL128(...)           \
121         CPPMAGIC_EVAL64(CPPMAGIC_EVAL64(__VA_ARGS__))
122 #define CPPMAGIC_EVAL256(...)           \
123         CPPMAGIC_EVAL128(CPPMAGIC_EVAL128(__VA_ARGS__))
124 #define CPPMAGIC_EVAL512(...)           \
125         CPPMAGIC_EVAL256(CPPMAGIC_EVAL256(__VA_ARGS__))
126 #define CPPMAGIC_EVAL1024(...)          \
127         CPPMAGIC_EVAL512(CPPMAGIC_EVAL512(__VA_ARGS__))
128 #define CPPMAGIC_EVAL(...)              CPPMAGIC_EVAL1024(__VA_ARGS__)
129
130 /**
131  * CPPMAGIC_DEFER1, CPPMAGIC_DEFER2 - defer expansion
132  */
133 #define CPPMAGIC_DEFER1(a_)     a_ CPPMAGIC_NOTHING()
134 #define CPPMAGIC_DEFER2(a_)     a_ CPPMAGIC_NOTHING CPPMAGIC_NOTHING()()
135
136 /**
137  * CPPMAGIC_MAP - iterate another macro across arguments
138  * @m: name of a one argument macro
139  *
140  * CPPMAGIC_MAP(@m, @a1, @a2, ... @an)
141  *      expands to the expansion of @m(@a1) , @m(@a2) , ... , @m(@an)
142  */
143 #define _CPPMAGIC_MAP_()                _CPPMAGIC_MAP
144 #define _CPPMAGIC_MAP(m_, a_, ...)                                      \
145         m_(a_)                                                          \
146         CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
147                 (, CPPMAGIC_DEFER2(_CPPMAGIC_MAP_)()(m_, __VA_ARGS__))  \
148                 ()
149 #define CPPMAGIC_MAP(m_, ...)                                           \
150         CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
151                 (CPPMAGIC_EVAL(_CPPMAGIC_MAP(m_, __VA_ARGS__)))         \
152                 ()
153
154 /**
155  * CPPMAGIC_2MAP - iterate another macro across pairs of arguments
156  * @m: name of a two argument macro
157  *
158  * CPPMAGIC_2MAP(@m, @a1, @b1, @a2, @b2, ..., @an, @bn)
159  *      expands to the expansion of
160  *               @m(@a1, @b1) , @m(@a2, @b2) , ... , @m(@an, @bn)
161  */
162 #define _CPPMAGIC_2MAP_()               _CPPMAGIC_2MAP
163 #define _CPPMAGIC_2MAP(m_, a_, b_, ...)                         \
164         m_(a_, b_)                                                      \
165         CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
166                 (, CPPMAGIC_DEFER2(_CPPMAGIC_2MAP_)()(m_, __VA_ARGS__)) \
167                 ()
168 #define CPPMAGIC_2MAP(m_, ...)                                  \
169         CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
170                 (CPPMAGIC_EVAL(_CPPMAGIC_2MAP(m_, __VA_ARGS__)))        \
171                 ()
172
173 /**
174  * CPPMAGIC_JOIN - separate arguments with given delimiter
175  * @d: delimiter
176  *
177  * CPPMAGIC_JOIN(@d, @a1, @a2, ..., @an)
178  *      expands to the expansion of @a1 @d @a2 @d ... @d @an
179  */
180 #define _CPPMAGIC_JOIN_()               _CPPMAGIC_JOIN
181 #define _CPPMAGIC_JOIN(d_, a_, ...)                                     \
182         a_                                                              \
183         CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
184                 (d_ CPPMAGIC_DEFER2(_CPPMAGIC_JOIN_)()(d_, __VA_ARGS__)) \
185                 ()
186 #define CPPMAGIC_JOIN(d_, ...)                                  \
187         CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
188                 (CPPMAGIC_EVAL(_CPPMAGIC_JOIN(d_, __VA_ARGS__)))        \
189                 ()
190
191 #endif /* CCAN_CPPMAGIC_H */