|
24 | 24 | /****************************************/ |
25 | 25 | // LOGIC |
26 | 26 |
|
| 27 | +#define fm_true 1 |
| 28 | +#define fm_false 0 |
| 29 | + |
27 | 30 | #define fm_compl(v) fm_cat(fm_compl_, v) |
28 | 31 | #define fm_compl_0 1 |
29 | 32 | #define fm_compl_1 0 |
|
81 | 84 | #define fm_tail(...) fm__tail(__VA_ARGS__) |
82 | 85 | #define fm__tail(x, ...) __VA_ARGS__ |
83 | 86 |
|
84 | | -#define fm_or_default(...) \ |
85 | | - fm_iif(fm_va_01(__VA_ARGS__))(__VA_ARGS__) |
86 | 87 | #define fm_va_single(...) fm__va_single(__VA_ARGS__, fm__comma) |
87 | 88 | #define fm_va_many(...) fm__va_many(__VA_ARGS__, fm__comma) |
88 | 89 | #define fm__va_single(x, y, ...) fm__va_result(y, 1, 0) |
89 | 90 | #define fm__va_many(x, y, ...) fm__va_result(y, 0, 1) |
90 | | -#define fm__va_result(x, y, res, ...) res |
| 91 | +#define fm__va_result(...) fm__va_result_fin(__VA_ARGS__) |
| 92 | +#define fm__va_result_fin(x, y, res, ...) res |
91 | 93 |
|
92 | 94 | #define fm_no_va fm_is_empty |
93 | 95 | #define fm_va_01 fm_isnt_empty |
94 | | -#define fm_va_01n(...) fm_cat3(fm__va_01n_, fm__isnt_empty(__VA_ARGS__), fm_va_many(__VA_ARGS__)) |
95 | | -#define fm__va_01n_00 0 |
96 | | -#define fm__va_01n_10 1 |
97 | | -#define fm__va_01n_11 n |
98 | 96 |
|
99 | | -#if !__STRICT_ANSI__ |
| 97 | +#ifndef FM_USE_STRICT |
| 98 | + #if defined(__STRICT_ANSI__) || defined(_MSC_VER) /* well, clang-cl doesn't allow to distinguish std mode */ |
| 99 | + #define FM_USE_STRICT |
| 100 | + #endif |
| 101 | +#endif |
| 102 | + |
| 103 | +#ifndef FM_USE_STRICT |
100 | 104 | #define fm_is_empty(...) fm__is_empty(__VA_ARGS__) |
101 | 105 | #define fm__is_empty(...) fm_va_single(~, ##__VA_ARGS__) |
102 | 106 | #define fm_isnt_empty(...) fm__isnt_empty(__VA_ARGS__) |
103 | 107 | #define fm__isnt_empty(...) fm_va_many(~, ##__VA_ARGS__) |
| 108 | + |
| 109 | +#define fm_va_01n(...) fm_cat3(fm__va_01n_, fm__isnt_empty(__VA_ARGS__), fm_va_many(__VA_ARGS__)) |
| 110 | +#define fm__va_01n_00 0 |
| 111 | +#define fm__va_01n_10 1 |
| 112 | +#define fm__va_01n_11 n |
| 113 | + |
| 114 | +#define fm_when_isnt_empty(...) fm_cat(fm__when_, fm__isnt_empty(__VA_ARGS__)) |
104 | 115 | #else |
105 | 116 | #define fm_is_empty(...) fm_and(fm__is_emptyfirst(__VA_ARGS__), fm_va_single(__VA_ARGS__)) |
106 | 117 | #define fm_isnt_empty(...) fm_nand(fm__is_emptyfirst(__VA_ARGS__), fm_va_single(__VA_ARGS__)) |
107 | 118 |
|
108 | 119 | #define fm__is_emptyfirst(x, ...) fm_iif(fm_is_tuple(x))(0)(fm__is_emptyfirst_impl(x)) |
109 | | -#define fm__is_emptyfirst_impl(x,...) fm_tuple_2((\ |
110 | | - fm__is_emptyfirst_do1 x (fm__is_emptyfirst_do2), 1, 0)) |
| 120 | +#define fm__is_emptyfirst_impl(x,...) fm__va_result(\ |
| 121 | + fm__is_emptyfirst_do1 x (fm__is_emptyfirst_do2), 1, 0) |
111 | 122 | #define fm__is_emptyfirst_do1(F) F() |
112 | 123 | #define fm__is_emptyfirst_do2(...) , |
| 124 | + |
| 125 | +#define fm_when_isnt_empty(...) fm_cat(fm__when_, fm_isnt_empty(__VA_ARGS__)) |
| 126 | + |
| 127 | +#define fm_va_01n(...) fm_cat3(fm__va_01n_, fm__is_emptyfirst(__VA_ARGS__), fm_va_many(__VA_ARGS__)) |
| 128 | +#define fm__va_01n_10 0 |
| 129 | +#define fm__va_01n_00 1 |
| 130 | +#define fm__va_01n_01 n |
| 131 | +#define fm__va_01n_11 n |
113 | 132 | #endif |
114 | 133 |
|
115 | | -#define fm_when_isnt_empty(...) fm_cat(fm__when_, fm__isnt_empty(__VA_ARGS__)) |
| 134 | +#define fm_or_default(...) \ |
| 135 | + fm_iif(fm_va_01(__VA_ARGS__))(__VA_ARGS__) |
| 136 | + |
116 | 137 | #define fm_va_comma(...) \ |
117 | 138 | fm_when_isnt_empty(__VA_ARGS__)(fm__comma) |
118 | 139 | #define fm_va_comma_fun(...) \ |
|
127 | 148 | #define fm__is_tuple_help(...) , |
128 | 149 | #define fm__is_tuple_(...) fm__is_tuple_choose(__VA_ARGS__) |
129 | 150 |
|
130 | | -#define fm_tuple_expand(x) fm_expand x |
131 | | -#define fm_tuple_tag(x) fm_head x |
132 | | -#define fm_tuple_data(x) fm_tail x |
133 | | -#define fm_tuple_0(x) fm_head x |
134 | | -#define fm_tuple_1(x) fm__tuple_1 x |
135 | | -#define fm__tuple_1(_0, _1, ...) _1 |
136 | | -#define fm_tuple_2(x) fm__tuple_2 x |
137 | | -#define fm__tuple_2(_0, _1, _2, ...) _2 |
138 | | - |
139 | | -#define fm_tuple_tag_or_0(x) fm__tuple_tag_or_0_(fm__tuple_tag_or_0_help x, 0) |
140 | | -#define fm__tuple_tag_or_0_(...) fm__tuple_tag_or_0_choose(__VA_ARGS__) |
141 | | -#define fm__tuple_tag_or_0_choose(a,x,...) x |
142 | | -#define fm__tuple_tag_or_0_help(tag, ...) , tag |
143 | | - |
144 | | -#define fm_dispatch_tag_or_0(prefix, x) \ |
145 | | - fm_cat(prefix, fm_tuple_tag_or_0(x)) |
146 | | - |
147 | 151 | /****************************************/ |
148 | 152 | // Iteration |
149 | 153 |
|
|
160 | 164 |
|
161 | 165 | // recursion handle : delay macro expansion to next recursion iteration |
162 | 166 | #define fm_recurs(id) id fm_empty fm_empty() () |
163 | | -#define fm_recurs2(a,b) fm_cat fm_empty fm_empty() () (a,b) |
| 167 | +#define fm_recurs2(a,b) fm_cat fm_empty() (a,b) |
164 | 168 | #define fm_defer(id) id fm_empty() |
165 | 169 |
|
166 | 170 | #define fm_foreach_join(join, macro, ...) \ |
167 | | - fm_foreach_join_(fm_empty, join, macro, __VA_ARGS__) |
168 | | -#define fm_foreach_join_(join1, join2, macro, ...) \ |
169 | | - fm_cat(fm_foreach_join_, fm_va_01n(__VA_ARGS__))(join1, join2, macro, __VA_ARGS__) |
| 171 | + fm_cat(fm_foreach_join_, fm_va_01n(__VA_ARGS__))(fm_empty, join, macro, __VA_ARGS__) |
170 | 172 | #define fm_foreach_join_0(join1, join2, macro, ...) |
171 | 173 | #define fm_foreach_join_1(join1, join2, macro, x) \ |
172 | 174 | join1() macro(x) |
173 | 175 | #define fm_foreach_join_n(join1, join2, macro, x, y, ...) \ |
174 | 176 | join1() macro(x) \ |
175 | 177 | join2() macro(y) \ |
176 | | - fm_recurs2(fm_, foreach_join_) (join2, join2, macro, __VA_ARGS__) |
| 178 | + fm_recurs2(fm_foreach_join_, fm_va_01n(__VA_ARGS__))(join2, join2, macro, __VA_ARGS__) |
177 | 179 |
|
178 | 180 | #define fm_foreach(macro, ...) \ |
179 | 181 | fm_foreach_join(fm_empty, macro, __VA_ARGS__) |
180 | 182 | #define fm_foreach_comma(macro, ...) \ |
181 | 183 | fm_foreach_join(fm_comma, macro, __VA_ARGS__) |
182 | 184 |
|
183 | 185 | #define fm_foreach_arg_join(join, macro, arg, ...) \ |
184 | | - fm_foreach_arg_join_(fm_empty, join, macro, arg, __VA_ARGS__) |
185 | | -#define fm_foreach_arg_join_(join1, join2, macro, arg, ...) \ |
186 | | - fm_cat(fm_foreach_arg_join_, fm_va_01n(__VA_ARGS__))(join1, join2, macro, arg, __VA_ARGS__) |
| 186 | + fm_cat(fm_foreach_arg_join_, fm_va_01n(__VA_ARGS__))(fm_empty, join, macro, arg, __VA_ARGS__) |
187 | 187 | #define fm_foreach_arg_join_0(join1, join2, macro, ...) |
188 | 188 | #define fm_foreach_arg_join_1(join1, join2, macro, arg, x) \ |
189 | 189 | join1() macro(arg, x) |
190 | 190 | #define fm_foreach_arg_join_n(join1, join2, macro, arg, x, y, ...) \ |
191 | 191 | join1() macro(arg, x) \ |
192 | 192 | join2() macro(arg, y) \ |
193 | | - fm_recurs2(fm_, foreach_arg_join_) (join2, join2, macro, arg, __VA_ARGS__) |
| 193 | + fm_recurs2(fm_foreach_arg_join_, fm_va_01n(__VA_ARGS__))(join1, join2, macro, arg, __VA_ARGS__) |
194 | 194 |
|
195 | 195 | #define fm_foreach_arg(macro, arg, ...) \ |
196 | 196 | fm_foreach_arg_join(fm_empty, macro, arg, __VA_ARGS__) |
197 | 197 | #define fm_foreach_arg_comma(macro, arg, ...) \ |
198 | 198 | fm_foreach_arg_join(fm_comma, macro, arg, __VA_ARGS__) |
199 | 199 |
|
200 | 200 | #define fm_foreach_tuple_join(join, macro, ...) \ |
201 | | - fm_foreach_tuple_join_(fm_empty, join, macro, __VA_ARGS__) |
202 | | -#define fm_foreach_tuple_join_(join1, join2, macro, ...) \ |
203 | | - fm_cat(fm_foreach_tuple_join_, fm_va_01n(__VA_ARGS__))(join1, join2, macro, __VA_ARGS__) |
| 201 | + fm_cat(fm_foreach_tuple_join_, fm_va_01n(__VA_ARGS__))(fm_empty, join, macro, __VA_ARGS__) |
204 | 202 | #define fm_foreach_tuple_join_0(join1, join2, macro, ...) |
205 | 203 | #define fm_foreach_tuple_join_1(join1, join2, macro, x) \ |
206 | 204 | join1() macro x |
207 | 205 | #define fm_foreach_tuple_join_n(join1, join2, macro, x, y, ...) \ |
208 | 206 | join1() macro x \ |
209 | 207 | join2() macro y \ |
210 | | - fm_recurs2(fm_, foreach_tuple_join_) (join2, join2, macro, __VA_ARGS__) |
| 208 | + fm_recurs2(fm_foreach_tuple_join_, fm_va_01n(__VA_ARGS__))(join2, join2, macro, __VA_ARGS__) |
211 | 209 |
|
212 | 210 | #define fm_foreach_tuple(macro, ...) \ |
213 | 211 | fm_foreach_tuple_join(fm_empty, macro, __VA_ARGS__) |
214 | 212 | #define fm_foreach_tuple_comma(macro, ...) \ |
215 | 213 | fm_foreach_tuple_join(fm_comma, macro, __VA_ARGS__) |
216 | 214 |
|
217 | 215 | #define fm_foreach_tuple_arg_join(join, macro, arg, ...) \ |
218 | | - fm_foreach_tuple_arg_join_(fm_empty, join, macro, arg, __VA_ARGS__) |
219 | | -#define fm_foreach_tuple_arg_join_(join1, join2, macro, arg, ...) \ |
220 | | - fm_cat(fm_foreach_tuple_arg_join_, fm_va_01n(__VA_ARGS__))(join1, join2, macro, arg, __VA_ARGS__) |
| 216 | + fm_cat(fm_foreach_tuple_arg_join_, fm_va_01n(__VA_ARGS__))(fm_empty, join, macro, arg, __VA_ARGS__) |
221 | 217 | #define fm_foreach_tuple_arg_join_0(join1, join2, macro, ...) |
222 | 218 | #define fm_foreach_tuple_arg_join_1(join1, join2, macro, arg, x) \ |
223 | 219 | join1() fm_apply(macro, arg, fm_expand x) |
224 | 220 | #define fm_foreach_tuple_arg_join_n(join1, join2, macro, arg, x, y, ...) \ |
225 | 221 | join1() fm_apply(macro, arg, fm_expand x) \ |
226 | 222 | join2() fm_apply(macro, arg, fm_expand y) \ |
227 | | - fm_recurs2(fm_, foreach_tuple_arg_join_) (join2, join2, macro, arg, __VA_ARGS__) |
| 223 | + fm_recurs2(fm_foreach_tuple_arg_join_, fm_va_01n(__VA_ARGS__))(join1, join2, macro, arg, __VA_ARGS__) |
228 | 224 |
|
229 | 225 | #define fm_foreach_tuple_arg(macro, arg, ...) \ |
230 | 226 | fm_foreach_tuple_arg_join(fm_empty, macro, arg, __VA_ARGS__) |
|
0 commit comments