• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Pigweed Authors
2 //
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
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
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
13 // the License.
14 
15 #pragma once
16 
17 // Preprocessor boolean operation macros that evaluate to 0 or 1.
18 //
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:
21 //
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.
27 //
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:
31 //
32 //   #if RELEASE && OPTIMIZED
33 //
34 // However, there are cases when a literal 0 or 1 is required. For example:
35 //
36 //   #define SELECT_ALGORITHM() PW_CONCAT(ALGO_, PW_AND(RELEASE, OPTIMIZED))
37 //
38 // SELECT_ALGORITHM evaluates to ALGO_0 or ALGO_1, depending on whether RELEASE
39 // and OPTIMIZED are set to 1.
40 
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
48 
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()
52 #define _PW_OR_00() 0
53 #define _PW_OR_01() 1
54 #define _PW_OR_10() 1
55 #define _PW_OR_11() 1
56 
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()
60 #define _PW_NOT_0() 1
61 #define _PW_NOT_1() 0
62 
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
70 
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))
75