*/
#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 */
int main(void)
{
- plan_tests(7);
+ plan_tests(21);
CHECK1(CPPMAGIC_NOTHING(), "");
CHECK1(CPPMAGIC_GLUE2(a, b), "ab");
CHECK1(CPPMAGIC_2ND(a, b), "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 */
return exit_status();
}