P99
p99_logical.h
Go to the documentation of this file.
1 /* This may look like nonsense, but it really is -*- mode: C; coding: utf-8 -*- */
2 /* */
3 /* Except for parts copied from previous work and as explicitly stated below, */
4 /* the author and copyright holder for this work is */
5 /* (C) copyright 2010-2013 Jens Gustedt, INRIA, France */
6 /* */
7 /* This file is free software; it is part of the P99 project. */
8 /* */
9 /* Licensed under the Apache License, Version 2.0 (the "License"); */
10 /* you may not use this file except in compliance with the License. */
11 /* You may obtain a copy of the License at */
12 /* */
13 /* http://www.apache.org/licenses/LICENSE-2.0 */
14 /* */
15 /* Unless required by applicable law or agreed to in writing, software */
16 /* distributed under the License is distributed on an "AS IS" BASIS, */
17 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
18 /* See the License for the specific language governing permissions and */
19 /* limitations under the License. */
20 /* */
21 #ifndef P99_LOGICAL_H_
22 # define P99_LOGICAL_H_
23 
30 #include "p99_args.h"
31 #include "p99_list.h"
32 
54 #define P99_IS_EQ(_0, _1) P99_HAS_COMMA(P99_PASTE4(P00_IS_, _0, _EQ_, _1)())
55 
56 
66 #define P99_LOGIC_EVAL(_0) P00_EVAL_0(P99_IS_EMPTY(_0), P99_IS_EQ_0(_0))
67 
68 #define P00_EVAL_0(_0, _1) P99_PASTE3(P00_EVAL_, _0, _1)
69 
70 #define P00_EVAL_00 1
71 #define P00_EVAL_10 0
72 #define P00_EVAL_01 0
73 /* should never happen */
74 #define P00_EVAL_11 WEIRD_EVALUATION_ERROR
75 
85 #define P99_LOGIC_NOT(A) P00_NOT_0(P99_IS_EMPTY(_0), P99_IS_EQ_0(_0))
86 
87 #define P00_NOT_0(_0, _1) P99_PASTE3(P00_NOT_, _0, _1)
88 
89 #define P00_NOT_00 1
90 #define P00_NOT_10 0
91 #define P00_NOT_01 1
92 /* should never happen */
93 #define P00_NOT_11 WEIRD_NEGATION_ERROR
94 
103 #define P99_LOGIC_XOR(A, B) P99_IS_EQ(P99_LOGIC_NOT(A), P99_LOGIC_EVAL(B))
104 
105 
114 #define P99_LOGIC_OR(A, B) P00_LOGIC_OR(P99_LOGIC_EVAL(A), P99_LOGIC_EVAL(B))
115 
116 
117 #define P00_LOGIC_OR(_0, _1) P99_PASTE3(P00_LOGIC_OR_, _0, _1)
118 
119 #define P00_LOGIC_OR_00 0
120 #define P00_LOGIC_OR_10 1
121 #define P00_LOGIC_OR_01 1
122 #define P00_LOGIC_OR_11 1
123 
132 #define P99_LOGIC_AND(A, B) P00_LOGIC_AND(P99_LOGIC_EVAL(A), P99_LOGIC_EVAL(B))
133 
134 
135 #define P00_LOGIC_AND(_0, _1) P99_PASTE3(P00_LOGIC_AND_, _0, _1)
136 
137 #define P00_LOGIC_AND_00 0
138 #define P00_LOGIC_AND_10 0
139 #define P00_LOGIC_AND_01 0
140 #define P00_LOGIC_AND_11 1
141 
142 
143 
158 #define P99_IS_VOID(...) P00_IS_VOID(P99_IS_EMPTY(__VA_ARGS__), P99_IS_EQ_void(__VA_ARGS__))
159 
160 #define P00_IS_VOID(_0, _1) P99_PASTE3(P00_IS_VOID_, _0, _1)
161 
162 #define P00_IS_VOID_00 0
163 #define P00_IS_VOID_01 1
164 #define P00_IS_VOID_10 1
165 /* should not happen */
166 #define P00_IS_VOID_11 WEIRD_VOID_ARG_ERROR
167 
168 #define P99_IS_INT(...) P00_IS_INT(P99_IS_EQ_signed(__VA_ARGS__), P99_IS_EQ_int(__VA_ARGS__))
169 
170 #define P00_IS_INT(_0, _1) P99_PASTE3(P00_IS_INT_, _0, _1)
171 
172 #define P00_IS_INT_00 0
173 #define P00_IS_INT_01 1
174 #define P00_IS_INT_10 1
175 /* should not happen */
176 #define P00_IS_INT_11 WEIRD_INT_ARG_ERROR
177 
178 #define P99_IF_INT(TOK) P99_IF_EQ_1(P99_IS_INT(TOK))
179 
181 #define P99_IS_LT(_0, _1) P00_LT( P99_IS_EQ_0(_1), P99_CHS(_0, P99_SELS(_1, P00_ALL_ONES()), P00_ALL_ZEROES()))
182 #define P00_LT(_0, _1) P99_PASTE2(P00_LT_, _0)(_1)
183 
184 #define P00_LT_0(_0) _0
185 #define P00_LT_1(_0) 0
186 
188 #define P99_IS_GE(_0, _1) P00_GE( P99_IS_EQ_0(_1), P99_CHS(_0, P99_SELS(_1, P00_ALL_ZEROES()), P00_ALL_ONES()))
189 #define P00_GE(_0, _1) P99_PASTE2(P00_GE_, _0)(_1)
190 
191 #define P00_GE_0(_0) _0
192 #define P00_GE_1(_0) 1
193 
195 #define P99_IS_GT(_0, _1) P99_IS_LT(_1, _0)
196 
197 #define P99_IS_LE(_0, _1) P99_IS_GE(_1, _0)
198 
217 #define P99_ADD(_0, _1) \
218 P00_ADD_(_0, _1, \
219  P99_IS_EQ_0(_0), \
220  P99_IS_EQ_0(_1), \
221  P99_NARG( \
222  P99_SELS(_0, P00_ALL_ZEROES()), \
223  P99_SELS(_1, P00_ALL_ZEROES())))
224 
225 
226 #define P00_ADD_(_0, _1, _2, _3, _4) P99_PASTE3(P00_ADD_, _2, _3)(_0, _1, _4)
227 
228 #define P00_ADD_00(_0, _1, _2) _2
229 #define P00_ADD_01(_0, _1, _2) _0
230 #define P00_ADD_10(_0, _1, _2) _1
231 #define P00_ADD_11(_0, _1, _2) 0
232 
233 
243 #define P99_MINUS(_0, _1) P00_MINUS(_0, _1, P99_IS_EQ(_0, _1), P99_IS_EQ_0(_0), P99_IS_EQ_0(_1))
244 #define P00_MINUS(_0, _1, _2, _3, _4) P99_PASTE4(P00_MINUS_, _2, _3, _4)(_0, _1)
245 
246 #define P00_MINUS_000(_0, _1) P00_MINUS_(_0, _1, P99_IS_LT(_0, _1))
247 /* if one of _0 or _1 is 0, there is not much to do */
248 #define P00_MINUS_001(_0, _1) _0
249 #define P00_MINUS_010(_0, _1) P99_PASTE2(minus_, _1)
250 /* should not occur */
251 #define P00_MINUS_011(_0, _1) P99_WEIRD_MINUS_ARG_ERROR
252 /* whenever _0 and _1 are equal there is nothing to do */
253 #define P00_MINUS_100(_0, _1) 0
254 #define P00_MINUS_101(_0, _1) 0
255 #define P00_MINUS_110(_0, _1) 0
256 #define P00_MINUS_111(_0, _1) 0
257 
258 #define P00_MINUS_(_0, _1, _2) P99_PASTE2(P00_MINUS_, _2)(_0, _1)
259 
260 #define P00_MINUS_0(_0, _1) P00_MINUS__(_0, _1)
261 #define P00_MINUS_1(_0, _1) P99_PASTE2(minus_, P00_MINUS__(_1, _0))
262 
263 
264 
265 /* The general case both are non-zero and _0 is strictly greater than _1 */
266 #define P00_MINUS__(_0, _1) P99_NARG(P99_SKP(_1, P99_SELS(_0, P00_ALL_ZEROES())))
267 
268 
273 #define P99_PRED(N) P00_PRED(N)
274 #define P00_PRED(N) P00__PRED(P00_PRED_ , N)
275 #define P00__PRED(P, N) P ## N
276 
277 #define P00_PRED_0 minus_1
278 
282 #define P99_EVAL(EDEC) P99_PASTE2(P00_dec_eval_, EDEC)
283 
284 
292 #define P99_MUL(A, B) P99_PASTE3(P00_MUL_, P99_IS_EQ_0(A), P99_IS_EQ_0(B))(A, B)
293 
294 #define P00_MUL_00(A, B) P99_NARG(P99_DUPL(A, P99_SELS(B, P00_ALL_ONES())))
295 #define P00_MUL_01(A, B) 0
296 #define P00_MUL_10(A, B) 0
297 #define P00_MUL_11(A, B) 0
298 
299 
307 #define P99_MOD(A, B) P00_MOD(A, P99_DUPL(32, P99_SELS(B, P00_ASCENDING())))
308 #define P00_MOD(A, ...) P99_CHS(A, __VA_ARGS__)
309 
324 #define P99_LAST(...) P99_CHS(P99_PRED(P00_NARG(__VA_ARGS__)), __VA_ARGS__,)
325 
329 #define P99_ALLBUTLAST(...) P99_PASTE2(P00_PRE,P99_PRED(P00_NARG(__VA_ARGS__)))(__VA_ARGS__,)
330 
331 #define P00__PASTE(F, N, ...) F ## N(__VA_ARGS__)
332 #define P00_PASTE(N, ...) P00__PASTE(P99_PASTE, N, __VA_ARGS__)
333 
334 
357 #define P99_PASTE(...) P00_PASTE(P00_NARG(__VA_ARGS__), __VA_ARGS__)
358 
359 #define P00_EAT_FIRST(SEQ) P00_EAT_ ## SEQ
360 
361 #define P00_STARTS(TOK, SEQ) P99_IS_EQ(2, P99_NARG(P99_PASTE4(P00_TOK_, TOK, _STARTS_, SEQ)))
362 
363 
368 #endif /* !P99_LOGICAL_H_ */
p99_args.h
Providing macros that handle variadic macro argument lists.
p99_list.h
Basis macros to process the parameter list of a variadic macro.