1 // Copyright 2019 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
17 // Preprocessor boolean operation macros that evaluate to 0 or 1.
19 // These macros perform boolean operations in the C preprocessor that evaluate
20 // to a literal 1 or 0. They can be used for a few purposes:
22 // - Generate other macros that evaluate to a 1 or 0, instead of a
23 // parenthesized boolean expression.
24 // - Ensure that the operands are defined and evaluate to 1 or 0 themselves.
25 // - Write macros that conditionally use other macros by token pasting the
26 // resulting 1 or 0 to form a new macro name.
28 // These macros should not be used outside of macro definitions. Use normal C
29 // operators (&&, ||, !, ==, !=) instead. For example, to check whether two
30 // flags are set, the C operators are the best choice:
32 // #if RELEASE && OPTIMIZED
34 // However, there are cases when a literal 0 or 1 is required. For example:
36 // #define SELECT_ALGORITHM() PW_CONCAT(ALGO_, PW_AND(RELEASE, OPTIMIZED))
38 // SELECT_ALGORITHM evaluates to ALGO_0 or ALGO_1, depending on whether RELEASE
39 // and OPTIMIZED are set to 1.
41 // Boolean AND of two preprocessor expressions that evaluate to 0 or 1.
42 #define PW_AND(a, b) _PW_AND(a, b) // Expand the macro an extra time to
43 #define _PW_AND(a, b) _PW_AND_##a##b() // allow macro substitution to occur.
44 #define _PW_AND_00() 0
45 #define _PW_AND_01() 0
46 #define _PW_AND_10() 0
47 #define _PW_AND_11() 1
49 // Boolean OR of two preprocessor expressions that evaluate to 0 or 1.
50 #define PW_OR(a, b) _PW_OR(a, b)
51 #define _PW_OR(a, b) _PW_OR_##a##b()
57 // Boolean NOT of a preprocessor expression that evaluates to 0 or 1.
58 #define PW_NOT(value) _PW_NOT(value)
59 #define _PW_NOT(value) _PW_NOT_##value()
63 // Boolean XOR of two preprocessor expressions that evaluate to 0 or 1.
64 #define PW_XOR(a, b) _PW_XOR(a, b)
65 #define _PW_XOR(a, b) _PW_XOR_##a##b()
66 #define _PW_XOR_00() 0
67 #define _PW_XOR_01() 1
68 #define _PW_XOR_10() 1
69 #define _PW_XOR_11() 0
71 // Boolean NAND, NOR, and XNOR of expressions that evaluate to 0 or 1.
72 #define PW_NAND(a, b) PW_NOT(PW_AND(a, b))
73 #define PW_NOR(a, b) PW_NOT(PW_OR(a, b))
74 #define PW_XNOR(a, b) PW_NOT(PW_XOR(a, b))