[binoculars-ng] use Geometry in the dataframe.
[hkl.git] / third-party / metalang99 / aux.h
bloba26a1ac017a7431294249e9e73be58dcbe9a3be7
1 /**
2 * @file
3 * Auxiliary macros.
4 */
6 #ifndef METALANG99_AUX_H
7 #define METALANG99_AUX_H
9 #include <metalang99/lang.h>
10 #include <metalang99/priv/compiler_attr.h>
12 // Desugaring {
13 /**
14 * Concatenates @p x with @p y and evaluates the result.
16 * # Examples
18 * @code
19 * #include <metalang99/aux.h>
21 * #define ABC123 v(Billie Jean)
23 * // Billie Jean
24 * M_catEval(v(ABC), v(123))
26 * // ERROR: 123ABC is not a valid Metalang99 term.
27 * M_catEval(v(123), v(ABC))
28 * @endcode
30 #define METALANG99_catEval(x, y) METALANG99_call(METALANG99_catEval, x y)
32 /**
33 * Concatenates @p x with @p y, leaving the result unevaluated.
35 * # Examples
37 * @code
38 * #include <metalang99/aux.h>
40 * #define ABC123 Billie Jean
42 * // Billie Jean
43 * M_cat(v(ABC), v(123))
45 * // 123ABC
46 * M_cat(v(123), v(ABC))
47 * @endcode
49 #define METALANG99_cat(x, y) METALANG99_call(METALANG99_cat, x y)
51 /**
52 * Stringifies provided arguments.
54 * # Examples
56 * @code
57 * #include <metalang99/aux.h>
59 * // "Billie Jean"
60 * M_stringify(v(Billie Jean))
61 * @endcode
63 #define METALANG99_stringify(...) METALANG99_call(METALANG99_stringify, __VA_ARGS__)
65 /**
66 * Evaluates to nothing.
68 #define METALANG99_empty() METALANG99_call(METALANG99_empty, )
70 /**
71 * Evaluates to its arguments.
73 * # Examples
75 * @code
76 * #include <metalang99/aux.h>
78 * // 1, 2, 3
79 * M_id(v(1, 2, 3))
80 * @endcode
82 #define METALANG99_id(...) METALANG99_call(METALANG99_id, __VA_ARGS__)
84 /**
85 * Transforms a sequence of arguments into a parenthesised normal form.
87 * # Examples
89 * @code
90 * #include <metalang99/aux.h>
92 * // (v(1, 2, 3))
93 * M_parenthesiseEval(v(1, 2, 3))
94 * @endcode
96 #define METALANG99_parenthesiseEval(...) METALANG99_call(METALANG99_parenthesiseEval, __VA_ARGS__)
98 /**
99 * Parenthesises a sequence of arguments.
101 * # Examples
103 * @code
104 * #include <metalang99/aux.h>
106 * // (1, 2, 3)
107 * M_parenthesise(v(1, 2, 3))
108 * @endcode
110 #define METALANG99_parenthesise(...) METALANG99_call(METALANG99_parenthesise, __VA_ARGS__)
113 * Unparenthesises a sequence of arguments and evaluates the result.
115 * If @p x begins with an opening parenthesis, it must also end with a closing parenthesis, e.g. `()
116 * 123` is disallowed.
118 * # Examples
120 * @code
121 * #include <metalang99/aux.h>
123 * // 1, 2, 3
124 * M_unparenthesiseEval(v((v(1, 2, 3))))
125 * @endcode
127 #define METALANG99_unparenthesiseEval(x) METALANG99_call(METALANG99_unparenthesiseEval, x)
130 * Unparenthesises a sequence of arguments, leaving the result unevaluated.
132 * If @p x begins with an opening parenthesis, it must also end with a closing parenthesis, e.g. `()
133 * 123` is disallowed.
135 * # Examples
137 * @code
138 * #include <metalang99/aux.h>
140 * // 1, 2, 3
141 * M_unparenthesise(v((1, 2, 3)))
142 * @endcode
144 #define METALANG99_unparenthesise(x) METALANG99_call(METALANG99_unparenthesise, x)
147 * Tests whether @p x is inside parentheses or not.
149 * If @p x begins with an opening parenthesis, it must also end with a closing parenthesis, e.g. `()
150 * 123` is disallowed.
152 * # Examples
154 * @code
155 * #include <metalang99/aux.h>
157 * // 0
158 * M_isParenthesised(v(123))
160 * // 1
161 * M_isParenthesised(v((123)))
162 * @endcode
164 #define METALANG99_isParenthesised(x) METALANG99_call(METALANG99_isParenthesised, x)
167 * The inverse of #METALANG99_isParenthesised.
169 * If @p x begins with an opening parenthesis, it must also end with a closing parenthesis, e.g. `()
170 * 123` is disallowed.
172 * # Examples
174 * @code
175 * #include <metalang99/aux.h>
177 * // 1
178 * M_isUnparenthesised(v(123))
180 * // 0
181 * M_isUnparenthesised(v((123)))
182 * @endcode
184 #define METALANG99_isUnparenthesised(x) METALANG99_call(METALANG99_isUnparenthesised, x)
187 * Evaluates to @p x, skipping @p a.
189 * # Examples
191 * @code
192 * #include <metalang99/aux.h>
194 * // 123
195 * M_const(v(123), v(5))
196 * @endcode
198 #define METALANG99_const(x, a) METALANG99_call(METALANG99_const, x a)
201 * Evaluates to @p x, skipping @p a, and @p b.
203 * # Examples
205 * @code
206 * #include <metalang99/aux.h>
208 * // 123
209 * M_const2(v(123), v(5), v(6))
210 * @endcode
212 #define METALANG99_const2(x, a, b) METALANG99_call(METALANG99_const2, x a b)
215 * Evaluates to @p x, skipping @p a, @p b, and @p c.
217 * # Examples
219 * @code
220 * #include <metalang99/aux.h>
222 * // 123
223 * M_const3(v(123), v(5), v(6), v(7))
224 * @endcode
226 #define METALANG99_const3(x, a, b, c) METALANG99_call(METALANG99_const3, x a b c)
229 * Reverses the order of arguments of the binary function @p f.
231 * # Examples
233 * @code
234 * #include <metalang99/aux.h>
236 * // ABC123
237 * M_appl2(M_flip(v(M_catUnevaluated)), v(123), v(ABC))
238 * @endcode
240 #define METALANG99_flip(f) METALANG99_call(METALANG99_flip, f)
243 * Puts @p x before @p right.
245 * # Examples
247 * @code
248 * #include <metalang99/aux.h>
250 * // ! 0
251 * M_putBefore(v(0), v(!))
252 * @endcode
254 #define METALANG99_putBefore(right, x) METALANG99_call(METALANG99_putBefore, right x)
257 * Puts @p x after @p left.
259 * # Examples
261 * @code
262 * #include <metalang99/aux.h>
264 * // ! 0
265 * M_putAfter(v(!), v(0))
266 * @endcode
268 #define METALANG99_putAfter(left, x) METALANG99_call(METALANG99_putAfter, left x)
271 * Puts @p x between @p left and @p right.
273 * # Examples
275 * @code
276 * #include <metalang99/aux.h>
278 * // 16 + 9
279 * M_putBetween(v(16), v(9), v(+))
280 * @endcode
282 #define METALANG99_putBetween(left, right, x) METALANG99_call(METALANG99_putBetween, left right x)
285 * Consumes all its arguments and expands to emptiness.
287 * # Examples
289 * @code
290 * #include <metalang99/aux.h>
292 * // M_empty()
293 * M_consume(v(1, 2, 3))
294 * @endcode
296 #define METALANG99_consume(...) METALANG99_call(METALANG99_consume, __VA_ARGS__)
299 * Puts provided arguments into braces.
301 * Some code formatters behave strangely when encounter braces in macros (in different places) --
302 * this is why this macro exists.
304 * # Examples
306 * @code
307 * #include <metalang99/aux.h>
309 * // { int a, b, c; }
310 * M_braced(v(int a, b, c;))
311 * @endcode
313 #define METALANG99_braced(...) METALANG99_call(METALANG99_braced, __VA_ARGS__)
316 * Concatenates @p x with @p y as-is, without expanding them.
318 * # Examples
320 * @code
321 * #include <metalang99/aux.h>
323 * // This macro will not be expanded.
324 * #define ABC 7
326 * // ABC123
327 * M_catPrimitive(ABC, 123)
328 * @endcode
330 * @note This macro does not expand to an Metalang99 term: it is rather an ordinary preprocessor
331 * macro.
333 #define METALANG99_catPrimitive(x, y) x##y
336 * Stringifies @p x as-is, without expanding it.
338 * # Examples
340 * @code
341 * #include <metalang99/aux.h>
343 * // This macro will not be expanded.
344 * #define ABC 7
346 * // "ABC"
347 * M_stringifyPrimitive(ABC)
348 * @endcode
350 * @note This macro does not expand to an Metalang99 term: it is rather an ordinary preprocessor
351 * macro.
353 #define METALANG99_stringifyPrimitive(...) #__VA_ARGS__
356 * Forces to put a semicolon after itself.
358 * # Examples
360 * @code
361 * #include <metalang99/aux.h>
363 * M_semicolon();
364 * @endcode
366 * This macro is often useful when you want a user to put a semicolon after invocation of your
367 * macro:
369 * @code
370 * #include <metalang99/aux.h>
372 * #define WHEN(command, handler, ...) \
373 * if (incoming_command == command) { handler(__VA_ARGS__); } M_semicolon()
375 * WHEN(SomeCommand, handler, 1, 2, 3);
376 * @endcode
378 * @note This macro does not expand to an Metalang99 term: it is rather an ordinary preprocessor
379 * macro.
380 * @note This macro can be used both inside and outside of function bodies, in contrast to the `do {
381 * ... } while(0)` idiom. Technically, this macro just expands to an unused static variable
382 * declaration.
384 #define METALANG99_semicolon() \
385 static const char METALANG99_PRIV_CAT(metalang99_semicolon_, __LINE__) \
386 METALANG99_PRIV_COMPILER_ATTR_UNUSED
389 * The plain version of #METALANG99_cat.
391 #define METALANG99_catPlain(x, y) METALANG99_catPrimitive(x, y)
394 * The plain version of #METALANG99_stringify.
396 #define METALANG99_stringifyPlain(...) METALANG99_stringifyPrimitive(__VA_ARGS__)
399 * The plain version of #METALANG99_empty.
401 #define METALANG99_emptyPlain()
404 * The plain version of #METALANG99_id.
406 #define METALANG99_idPlain(...) __VA_ARGS__
409 * The plain version of #METALANG99_parenthesise.
411 #define METALANG99_parenthesisePlain(...) (__VA_ARGS__)
414 * The plain version of #METALANG99_unparenthesise.
416 #define METALANG99_unparenthesisePlain(x) METALANG99_PRIV_UNPARENTHESISE(x)
419 * The plain version of #METALANG99_isParenthesised.
421 #define METALANG99_isParenthesisedPlain(x) METALANG99_PRIV_IS_PARENTHESISED(x)
424 * The plain version of #METALANG99_isUnparenthesised.
426 #define METALANG99_isUnparenthesisedPlain(x) METALANG99_PRIV_IS_UNPARENTHESISED(x)
429 * The plain version of #METALANG99_consume.
431 #define METALANG99_consumePlain(...)
432 // }
434 #ifndef DOXYGEN_IGNORE
436 // Implementation {
437 #define METALANG99_catEval_IMPL(x, y) x##y
438 #define METALANG99_cat_IMPL(x, y) v(METALANG99_catPlain(x, y))
439 #define METALANG99_stringify_IMPL(...) v(METALANG99_stringifyPlain(__VA_ARGS__))
440 #define METALANG99_empty_IMPL() v(METALANG99_emptyPlain())
441 #define METALANG99_id_IMPL(...) v(METALANG99_idPlain(__VA_ARGS__))
442 #define METALANG99_parenthesiseEval_IMPL(...) v((v(__VA_ARGS__)))
443 #define METALANG99_parenthesise_IMPL(...) v(METALANG99_parenthesisePlain(__VA_ARGS__))
444 #define METALANG99_unparenthesiseEval_IMPL(x) METALANG99_PRIV_UNPARENTHESISE(x)
445 #define METALANG99_unparenthesise_IMPL(x) v(METALANG99_unparenthesisePlain(x))
446 #define METALANG99_isParenthesised_IMPL(x) v(METALANG99_isParenthesisedPlain(x))
447 #define METALANG99_isUnparenthesised_IMPL(x) v(METALANG99_isUnparenthesisedPlain(x))
448 #define METALANG99_const_IMPL(x, _a) v(x)
449 #define METALANG99_const2_IMPL(x, _a, _b) v(x)
450 #define METALANG99_const3_IMPL(x, _a, _b, _c) v(x)
451 #define METALANG99_flip_IMPL(f) METALANG99_callTrivial(METALANG99_appl, METALANG99_PRIV_flip, f)
452 #define METALANG99_PRIV_flip_IMPL(f, a, b) METALANG99_callTrivial(METALANG99_appl2, f, b, a)
453 #define METALANG99_putBefore_IMPL(right, x) v(x right)
454 #define METALANG99_putAfter_IMPL(left, x) v(left x)
455 #define METALANG99_putBetween_IMPL(left, right, x) v(left x right)
456 #define METALANG99_consume_IMPL(...) v(METALANG99_consumePlain(__VA_ARGS__))
457 #define METALANG99_braced_IMPL(...) v({__VA_ARGS__})
458 // }
460 // Arity specifiers {
461 #define METALANG99_catEval_ARITY 2
462 #define METALANG99_cat_ARITY 2
463 #define METALANG99_stringify_ARITY 1
464 #define METALANG99_empty_ARITY 1
465 #define METALANG99_id_ARITY 1
466 #define METALANG99_parenthesise_ARITY 1
467 #define METALANG99_unparenthesise_ARITY 1
468 #define METALANG99_unparenthesiseEval_ARITY 1
469 #define METALANG99_parenthesiseEval_ARITY 1
470 #define METALANG99_isUnparenthesised_ARITY 1
471 #define METALANG99_isParenthesised_ARITY 1
472 #define METALANG99_const_ARITY 2
473 #define METALANG99_const2_ARITY 3
474 #define METALANG99_const3_ARITY 4
475 #define METALANG99_flip_ARITY 1
476 #define METALANG99_putBefore_ARITY 2
477 #define METALANG99_putAfter_ARITY 2
478 #define METALANG99_putBetween_ARITY 3
479 #define METALANG99_consume_ARITY 1
480 #define METALANG99_braced_ARITY 1
482 #define METALANG99_PRIV_flip_ARITY 3
483 // }
485 // Aliases {
486 #ifndef METALANG99_NO_SMALL_PREFIX
488 #define M_catEval METALANG99_catEval
489 #define M_cat METALANG99_cat
490 #define M_stringify METALANG99_stringify
491 #define M_empty METALANG99_empty
492 #define M_id METALANG99_id
493 #define M_parenthesiseEval METALANG99_parenthesiseEval
494 #define M_parenthesise METALANG99_parenthesise
495 #define M_unparenthesiseEval METALANG99_unparenthesiseEval
496 #define M_unparenthesise METALANG99_unparenthesise
497 #define M_isParenthesised METALANG99_isParenthesised
498 #define M_isUnparenthesised METALANG99_isUnparenthesised
499 #define M_const METALANG99_const
500 #define M_const2 METALANG99_const2
501 #define M_const3 METALANG99_const3
502 #define M_flip METALANG99_flip
503 #define M_putBefore METALANG99_putBefore
504 #define M_putAfter METALANG99_putAfter
505 #define M_putBetween METALANG99_putBetween
506 #define M_consume METALANG99_consume
507 #define M_braced METALANG99_braced
508 #define M_catPrimitive METALANG99_catPrimitive
509 #define M_stringifyPrimitive METALANG99_stringifyPrimitive
510 #define M_semicolon METALANG99_semicolon
512 #define M_catPlain METALANG99_catPlain
513 #define M_stringifyPlain METALANG99_stringifyPlain
514 #define M_emptyPlain METALANG99_emptyPlain
515 #define M_idPlain METALANG99_idPlain
516 #define M_parenthesisePlain METALANG99_parenthesisePlain
517 #define M_unparenthesisePlain METALANG99_unparenthesisePlain
518 #define M_isParenthesisedPlain METALANG99_isParenthesisedPlain
519 #define M_isUnparenthesisedPlain METALANG99_isUnparenthesisedPlain
520 #define M_consumePlain METALANG99_consumePlain
522 #endif // METALANG99_NO_SMALL_PREFIX
523 // }
525 #endif // DOXYGEN_IGNORE
527 #endif // METALANG99_AUX_H