]> git.ozlabs.org Git - ccan/blob - ccan/cppmagic/cppmagic.h
b5c35782f78ca5e58ab16fa45bddb0649c87333c
[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 #endif /* CCAN_CPPMAGIC_H */