]> git.ozlabs.org Git - ccan/blobdiff - ccan/cppmagic/cppmagic.h
tal: allow notifiers on NULL.
[ccan] / ccan / cppmagic / cppmagic.h
index c4454e776392f4edff78ff8289d432ce4e09ddf4..f1f6868e550dd2377d8829fec8a62d88bc842d1d 100644 (file)
 #define CPPMAGIC_ISEMPTY(...)          \
        CPPMAGIC_ISZERO(CPPMAGIC_NONEMPTY(__VA_ARGS__))
 
+/*
+ * CPPMAGIC_IFELSE - preprocessor conditional
+ *
+ * CPPMAGIC_IFELSE(@cond)(@if)(@else)
+ *     expands to @else if @cond is '0', otherwise expands to @if
+ */
+#define _CPPMAGIC_IF_0(...)            _CPPMAGIC_IF_0_ELSE
+#define _CPPMAGIC_IF_1(...)            __VA_ARGS__ _CPPMAGIC_IF_1_ELSE
+#define _CPPMAGIC_IF_0_ELSE(...)       __VA_ARGS__
+#define _CPPMAGIC_IF_1_ELSE(...)
+#define _CPPMAGIC_IFELSE(cond_)                CPPMAGIC_GLUE2(_CPPMAGIC_IF_, cond_)
+#define CPPMAGIC_IFELSE(cond_)         \
+       _CPPMAGIC_IFELSE(CPPMAGIC_NONZERO(cond_))
+
+/**
+ * CPPMAGIC_EVAL - force multiple expansion passes
+ *
+ * Forces macros in the arguments to be expanded repeatedly (up to
+ * 1024 times) even when CPP would usually stop expanding.
+ */
+#define CPPMAGIC_EVAL1(...)            __VA_ARGS__
+#define CPPMAGIC_EVAL2(...)            \
+       CPPMAGIC_EVAL1(CPPMAGIC_EVAL1(__VA_ARGS__))
+#define CPPMAGIC_EVAL4(...)            \
+       CPPMAGIC_EVAL2(CPPMAGIC_EVAL2(__VA_ARGS__))
+#define CPPMAGIC_EVAL8(...)            \
+       CPPMAGIC_EVAL4(CPPMAGIC_EVAL4(__VA_ARGS__))
+#define CPPMAGIC_EVAL16(...)           \
+       CPPMAGIC_EVAL8(CPPMAGIC_EVAL8(__VA_ARGS__))
+#define CPPMAGIC_EVAL32(...)           \
+       CPPMAGIC_EVAL16(CPPMAGIC_EVAL16(__VA_ARGS__))
+#define CPPMAGIC_EVAL64(...)           \
+       CPPMAGIC_EVAL32(CPPMAGIC_EVAL32(__VA_ARGS__))
+#define CPPMAGIC_EVAL128(...)          \
+       CPPMAGIC_EVAL64(CPPMAGIC_EVAL64(__VA_ARGS__))
+#define CPPMAGIC_EVAL256(...)          \
+       CPPMAGIC_EVAL128(CPPMAGIC_EVAL128(__VA_ARGS__))
+#define CPPMAGIC_EVAL512(...)          \
+       CPPMAGIC_EVAL256(CPPMAGIC_EVAL256(__VA_ARGS__))
+#define CPPMAGIC_EVAL1024(...)         \
+       CPPMAGIC_EVAL512(CPPMAGIC_EVAL512(__VA_ARGS__))
+#define CPPMAGIC_EVAL(...)             CPPMAGIC_EVAL1024(__VA_ARGS__)
+
+/**
+ * CPPMAGIC_DEFER1, CPPMAGIC_DEFER2 - defer expansion
+ */
+#define CPPMAGIC_DEFER1(a_)    a_ CPPMAGIC_NOTHING()
+#define CPPMAGIC_DEFER2(a_)    a_ CPPMAGIC_NOTHING CPPMAGIC_NOTHING()()
+
+/**
+ * CPPMAGIC_MAP - iterate another macro across arguments
+ * @m: name of a one argument macro
+ *
+ * CPPMAGIC_MAP(@m, @a1, @a2, ... @an)
+ *     expands to the expansion of @m(@a1) , @m(@a2) , ... , @m(@an)
+ */
+#define _CPPMAGIC_MAP_()               _CPPMAGIC_MAP
+#define _CPPMAGIC_MAP(m_, a_, ...)                                     \
+       m_(a_)                                                          \
+       CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
+               (, CPPMAGIC_DEFER2(_CPPMAGIC_MAP_)()(m_, __VA_ARGS__))  \
+               ()
+#define CPPMAGIC_MAP(m_, ...)                                          \
+       CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
+               (CPPMAGIC_EVAL(_CPPMAGIC_MAP(m_, __VA_ARGS__)))         \
+               ()
+
+/**
+ * CPPMAGIC_2MAP - iterate another macro across pairs of arguments
+ * @m: name of a two argument macro
+ *
+ * CPPMAGIC_2MAP(@m, @a1, @b1, @a2, @b2, ..., @an, @bn)
+ *     expands to the expansion of
+ *              @m(@a1, @b1) , @m(@a2, @b2) , ... , @m(@an, @bn)
+ */
+#define _CPPMAGIC_2MAP_()              _CPPMAGIC_2MAP
+#define _CPPMAGIC_2MAP(m_, a_, b_, ...)                                \
+       m_(a_, b_)                                                      \
+       CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
+               (, CPPMAGIC_DEFER2(_CPPMAGIC_2MAP_)()(m_, __VA_ARGS__)) \
+               ()
+#define CPPMAGIC_2MAP(m_, ...)                                 \
+       CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
+               (CPPMAGIC_EVAL(_CPPMAGIC_2MAP(m_, __VA_ARGS__)))        \
+               ()
+
+/**
+ * CPPMAGIC_JOIN - separate arguments with given delimiter
+ * @d: delimiter
+ *
+ * CPPMAGIC_JOIN(@d, @a1, @a2, ..., @an)
+ *     expands to the expansion of @a1 @d @a2 @d ... @d @an
+ */
+#define _CPPMAGIC_JOIN_()              _CPPMAGIC_JOIN
+#define _CPPMAGIC_JOIN(d_, a_, ...)                                    \
+       a_                                                              \
+       CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
+               (d_ CPPMAGIC_DEFER2(_CPPMAGIC_JOIN_)()(d_, __VA_ARGS__)) \
+               ()
+#define CPPMAGIC_JOIN(d_, ...)                                 \
+       CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__))                 \
+               (CPPMAGIC_EVAL(_CPPMAGIC_JOIN(d_, __VA_ARGS__)))        \
+               ()
+
 #endif /* CCAN_CPPMAGIC_H */