cppmagic.h (6228B)
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 */