Metalang99
1.13.3
Full-blown preprocessor metaprogramming
variadics.h
Go to the documentation of this file.
1
10
#ifndef ML99_VARIADICS_H
11
#define ML99_VARIADICS_H
12
13
#include <metalang99/nat/inc.h>
14
#include <metalang99/priv/util.h>
15
16
#include <
metalang99/lang.h
>
17
35
#define ML99_variadicsCount(...) ML99_call(ML99_variadicsCount, __VA_ARGS__)
36
52
#define ML99_variadicsIsSingle(...) ML99_call(ML99_variadicsIsSingle, __VA_ARGS__)
53
68
#define ML99_variadicsGet(i) ML99_PRIV_CAT(ML99_PRIV_variadicsGet_, i)
69
84
#define ML99_variadicsTail(...) ML99_call(ML99_variadicsTail, __VA_ARGS__)
85
103
#define ML99_variadicsForEach(f, ...) ML99_call(ML99_variadicsForEach, f, __VA_ARGS__)
104
120
#define ML99_variadicsForEachI(f, ...) ML99_call(ML99_variadicsForEachI, f, __VA_ARGS__)
121
149
#define ML99_OVERLOAD(f, ...) ML99_PRIV_CAT(f, ML99_PRIV_VARIADICS_COUNT(__VA_ARGS__))(__VA_ARGS__)
150
151
#define ML99_VARIADICS_COUNT(...) ML99_PRIV_VARIADICS_COUNT(__VA_ARGS__)
152
#define ML99_VARIADICS_IS_SINGLE(...) ML99_PRIV_NOT(ML99_PRIV_CONTAINS_COMMA(__VA_ARGS__))
153
#define ML99_VARIADICS_GET(i) ML99_PRIV_CAT(ML99_PRIV_VARIADICS_GET_, i)
154
#define ML99_VARIADICS_TAIL(...) ML99_PRIV_TAIL(__VA_ARGS__)
155
156
#ifndef DOXYGEN_IGNORE
157
158
#define ML99_variadicsCount_IMPL(...) v(ML99_VARIADICS_COUNT(__VA_ARGS__))
159
#define ML99_variadicsIsSingle_IMPL(...) v(ML99_VARIADICS_IS_SINGLE(__VA_ARGS__))
160
161
#define ML99_PRIV_variadicsGet_0(...) ML99_call(ML99_PRIV_variadicsGet_0, __VA_ARGS__)
162
#define ML99_PRIV_variadicsGet_1(...) ML99_call(ML99_PRIV_variadicsGet_1, __VA_ARGS__)
163
#define ML99_PRIV_variadicsGet_2(...) ML99_call(ML99_PRIV_variadicsGet_2, __VA_ARGS__)
164
#define ML99_PRIV_variadicsGet_3(...) ML99_call(ML99_PRIV_variadicsGet_3, __VA_ARGS__)
165
#define ML99_PRIV_variadicsGet_4(...) ML99_call(ML99_PRIV_variadicsGet_4, __VA_ARGS__)
166
#define ML99_PRIV_variadicsGet_5(...) ML99_call(ML99_PRIV_variadicsGet_5, __VA_ARGS__)
167
#define ML99_PRIV_variadicsGet_6(...) ML99_call(ML99_PRIV_variadicsGet_6, __VA_ARGS__)
168
#define ML99_PRIV_variadicsGet_7(...) ML99_call(ML99_PRIV_variadicsGet_7, __VA_ARGS__)
169
170
#define ML99_PRIV_variadicsGet_0_IMPL(...) v(ML99_VARIADICS_GET(0)(__VA_ARGS__))
171
#define ML99_PRIV_variadicsGet_1_IMPL(...) v(ML99_VARIADICS_GET(1)(__VA_ARGS__))
172
#define ML99_PRIV_variadicsGet_2_IMPL(...) v(ML99_VARIADICS_GET(2)(__VA_ARGS__))
173
#define ML99_PRIV_variadicsGet_3_IMPL(...) v(ML99_VARIADICS_GET(3)(__VA_ARGS__))
174
#define ML99_PRIV_variadicsGet_4_IMPL(...) v(ML99_VARIADICS_GET(4)(__VA_ARGS__))
175
#define ML99_PRIV_variadicsGet_5_IMPL(...) v(ML99_VARIADICS_GET(5)(__VA_ARGS__))
176
#define ML99_PRIV_variadicsGet_6_IMPL(...) v(ML99_VARIADICS_GET(6)(__VA_ARGS__))
177
#define ML99_PRIV_variadicsGet_7_IMPL(...) v(ML99_VARIADICS_GET(7)(__VA_ARGS__))
178
179
#define ML99_PRIV_VARIADICS_GET_0(...) ML99_PRIV_VARIADICS_GET_AUX_0(__VA_ARGS__, ~)
180
#define ML99_PRIV_VARIADICS_GET_1(...) ML99_PRIV_VARIADICS_GET_AUX_1(__VA_ARGS__, ~)
181
#define ML99_PRIV_VARIADICS_GET_2(...) ML99_PRIV_VARIADICS_GET_AUX_2(__VA_ARGS__, ~)
182
#define ML99_PRIV_VARIADICS_GET_3(...) ML99_PRIV_VARIADICS_GET_AUX_3(__VA_ARGS__, ~)
183
#define ML99_PRIV_VARIADICS_GET_4(...) ML99_PRIV_VARIADICS_GET_AUX_4(__VA_ARGS__, ~)
184
#define ML99_PRIV_VARIADICS_GET_5(...) ML99_PRIV_VARIADICS_GET_AUX_5(__VA_ARGS__, ~)
185
#define ML99_PRIV_VARIADICS_GET_6(...) ML99_PRIV_VARIADICS_GET_AUX_6(__VA_ARGS__, ~)
186
#define ML99_PRIV_VARIADICS_GET_7(...) ML99_PRIV_VARIADICS_GET_AUX_7(__VA_ARGS__, ~)
187
188
#define ML99_PRIV_VARIADICS_GET_AUX_0(a, ...) a
189
#define ML99_PRIV_VARIADICS_GET_AUX_1(_a, b, ...) b
190
#define ML99_PRIV_VARIADICS_GET_AUX_2(_a, _b, c, ...) c
191
#define ML99_PRIV_VARIADICS_GET_AUX_3(_a, _b, _c, d, ...) d
192
#define ML99_PRIV_VARIADICS_GET_AUX_4(_a, _b, _c, _d, e, ...) e
193
#define ML99_PRIV_VARIADICS_GET_AUX_5(_a, _b, _c, _d, _e, f, ...) f
194
#define ML99_PRIV_VARIADICS_GET_AUX_6(_a, _b, _c, _d, _e, _f, g, ...) g
195
#define ML99_PRIV_VARIADICS_GET_AUX_7(_a, _b, _c, _d, _e, _f, _g, h, ...) h
196
197
#define ML99_variadicsTail_IMPL(...) v(ML99_VARIADICS_TAIL(__VA_ARGS__))
198
199
// ML99_variadicsForEach_IMPL {
200
201
#define ML99_variadicsForEach_IMPL(f, ...) \
202
ML99_PRIV_CAT(ML99_PRIV_variadicsForEach_, ML99_VARIADICS_IS_SINGLE(__VA_ARGS__)) \
203
(f, __VA_ARGS__)
204
#define ML99_PRIV_variadicsForEach_1(f, x) ML99_appl_IMPL(f, x)
205
#define ML99_PRIV_variadicsForEach_0(f, x, ...) \
206
ML99_TERMS(ML99_appl_IMPL(f, x), ML99_callUneval(ML99_variadicsForEach, f, __VA_ARGS__))
207
// } (ML99_variadicsForEach_IMPL)
208
209
// ML99_variadicsForEachI_IMPL {
210
211
#define ML99_variadicsForEachI_IMPL(f, ...) ML99_PRIV_variadicsForEachIAux_IMPL(f, 0, __VA_ARGS__)
212
213
#define ML99_PRIV_variadicsForEachIAux_IMPL(f, i, ...) \
214
ML99_PRIV_CAT(ML99_PRIV_variadicsForEachI_, ML99_VARIADICS_IS_SINGLE(__VA_ARGS__)) \
215
(f, i, __VA_ARGS__)
216
217
#define ML99_PRIV_variadicsForEachI_1(f, i, x) ML99_appl2_IMPL(f, x, i)
218
#define ML99_PRIV_variadicsForEachI_0(f, i, x, ...) \
219
ML99_TERMS( \
220
ML99_appl2_IMPL(f, x, i), \
221
ML99_callUneval(ML99_PRIV_variadicsForEachIAux, f, ML99_PRIV_INC(i), __VA_ARGS__))
222
// } (ML99_variadicsForEachI_IMPL)
223
224
/*
225
* The StackOverflow solution: <https://stackoverflow.com/a/2124385/13166656>.
226
*
227
* This macro supports at most 63 arguments because C99 allows implementations to handle only 127
228
* parameters/arguments per macro definition/invocation (C99 | 5.2.4 Environmental limits), and
229
* `ML99_PRIV_VARIADICS_COUNT_AUX` already accepts 64 arguments.
230
*/
231
// clang-format off
232
#define ML99_PRIV_VARIADICS_COUNT(...) \
233
ML99_PRIV_VARIADICS_COUNT_AUX( \
234
__VA_ARGS__, \
235
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, \
236
53, 52, 51, 50, 49, 48, 47, 46, 45, 44, \
237
43, 42, 41, 40, 39, 38, 37, 36, 35, 34, \
238
33, 32, 31, 30, 29, 28, 27, 26, 25, 24, \
239
23, 22, 21, 20, 19, 18, 17, 16, 15, 14, \
240
13, 12, 11, 10, 9, 8, 7, 6, 5, 4, \
241
3, 2, 1, ~)
242
243
#define ML99_PRIV_VARIADICS_COUNT_AUX( \
244
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
245
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
246
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
247
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
248
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
249
_51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
250
_61, _62, _63, x, ...) \
251
x
252
// clang-format on
253
254
// Arity specifiers {
255
256
#define ML99_variadicsCount_ARITY 1
257
#define ML99_variadicsIsSingle_ARITY 1
258
#define ML99_variadicsTail_ARITY 1
259
#define ML99_variadicsForEach_ARITY 2
260
#define ML99_variadicsForEachI_ARITY 2
261
262
#define ML99_PRIV_variadicsGet_0_ARITY 1
263
#define ML99_PRIV_variadicsGet_1_ARITY 1
264
#define ML99_PRIV_variadicsGet_2_ARITY 1
265
#define ML99_PRIV_variadicsGet_3_ARITY 1
266
#define ML99_PRIV_variadicsGet_4_ARITY 1
267
#define ML99_PRIV_variadicsGet_5_ARITY 1
268
#define ML99_PRIV_variadicsGet_6_ARITY 1
269
#define ML99_PRIV_variadicsGet_7_ARITY 1
270
// } (Arity specifiers)
271
272
#endif
// DOXYGEN_IGNORE
273
274
#endif
// ML99_VARIADICS_H
lang.h
The core metalanguage.
include
metalang99
variadics.h
Generated by
1.9.4