Commit f92c112c authored by David Gibson's avatar David Gibson

cppmagic: Logical operations

In order to implement fancier things, we need to represent truth values in
cpp.  We use '0' and '1' strings, like in C, but we need ways to get these
values from other conditions.

CPPMAGIC_ISZERO() and CPPMAGIC_NONZERO() test if the argument is '0' or
anything else (ISZERO doubles as a logical not).

CPPMAGIC_ISEMPTY() and CPPMAGIC_NON_EMPTY() expand to 0 or 1 depending on
whether they have any arguments at all or not.
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent ff71198b
...@@ -39,4 +39,49 @@ ...@@ -39,4 +39,49 @@
*/ */
#define CPPMAGIC_2ND(a_, b_, ...) b_ #define CPPMAGIC_2ND(a_, b_, ...) b_
/**
* CPPMAGIC_ISZERO - is argument '0'
*
* CPPMAGIC_ISZERO(@a)
* expands to '1' if @a is '0', otherwise expands to '0'.
*/
#define _CPPMAGIC_ISPROBE(...) CPPMAGIC_2ND(__VA_ARGS__, 0)
#define _CPPMAGIC_PROBE() $, 1
#define _CPPMAGIC_ISZERO_0 _CPPMAGIC_PROBE()
#define CPPMAGIC_ISZERO(a_) \
_CPPMAGIC_ISPROBE(CPPMAGIC_GLUE2(_CPPMAGIC_ISZERO_, a_))
/**
* CPPMAGIC_NONZERO - is argument not '0'
*
* CPPMAGIC_NONZERO(@a)
* expands to '0' if @a is '0', otherwise expands to '1'.
*/
#define CPPMAGIC_NONZERO(a_) CPPMAGIC_ISZERO(CPPMAGIC_ISZERO(a_))
/**
* CPPMAGIC_NONEMPTY - does the macro have any arguments?
*
* CPPMAGIC_NONEMPTY()
* expands to '0'
* CPPMAGIC_NONEMPTY(@a)
* CPPMAGIC_NONEMPTY(@a, ...)
* expand to '1'
*/
#define _CPPMAGIC_EOA() 0
#define CPPMAGIC_NONEMPTY(...) \
CPPMAGIC_NONZERO(CPPMAGIC_1ST(_CPPMAGIC_EOA __VA_ARGS__)())
/**
* CPPMAGIC_ISEMPTY - does the macro have no arguments?
*
* CPPMAGIC_ISEMPTY()
* expands to '1'
* CPPMAGIC_ISEMPTY(@a)
* CPPMAGIC_ISEMPTY(@a, ...)
* expand to '0'
*/
#define CPPMAGIC_ISEMPTY(...) \
CPPMAGIC_ISZERO(CPPMAGIC_NONEMPTY(__VA_ARGS__))
#endif /* CCAN_CPPMAGIC_H */ #endif /* CCAN_CPPMAGIC_H */
...@@ -17,7 +17,7 @@ static inline void check1(const char *orig, const char *expand, ...@@ -17,7 +17,7 @@ static inline void check1(const char *orig, const char *expand,
int main(void) int main(void)
{ {
plan_tests(7); plan_tests(21);
CHECK1(CPPMAGIC_NOTHING(), ""); CHECK1(CPPMAGIC_NOTHING(), "");
CHECK1(CPPMAGIC_GLUE2(a, b), "ab"); CHECK1(CPPMAGIC_GLUE2(a, b), "ab");
...@@ -29,6 +29,24 @@ int main(void) ...@@ -29,6 +29,24 @@ int main(void)
CHECK1(CPPMAGIC_2ND(a, b), "b"); CHECK1(CPPMAGIC_2ND(a, b), "b");
CHECK1(CPPMAGIC_2ND(a, b, c), "b"); CHECK1(CPPMAGIC_2ND(a, b, c), "b");
CHECK1(CPPMAGIC_ISZERO(0), "1");
CHECK1(CPPMAGIC_ISZERO(1), "0");
CHECK1(CPPMAGIC_ISZERO(123), "0");
CHECK1(CPPMAGIC_ISZERO(abc), "0");
CHECK1(CPPMAGIC_NONZERO(0), "0");
CHECK1(CPPMAGIC_NONZERO(1), "1");
CHECK1(CPPMAGIC_NONZERO(123), "1");
CHECK1(CPPMAGIC_NONZERO(abc), "1");
CHECK1(CPPMAGIC_NONEMPTY(), "0");
CHECK1(CPPMAGIC_NONEMPTY(0), "1");
CHECK1(CPPMAGIC_NONEMPTY(a, b, c), "1");
CHECK1(CPPMAGIC_ISEMPTY(), "1");
CHECK1(CPPMAGIC_ISEMPTY(0), "0");
CHECK1(CPPMAGIC_ISEMPTY(a, b, c), "0");
/* This exits depending on whether all tests passed */ /* This exits depending on whether all tests passed */
return exit_status(); return exit_status();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment