|
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