summary refs log tree commit diff
path: root/include/nm-macros-internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/nm-macros-internal.h')
-rw-r--r--include/nm-macros-internal.h98
1 files changed, 85 insertions, 13 deletions
diff --git a/include/nm-macros-internal.h b/include/nm-macros-internal.h
index 405051f3..170fb46c 100644
--- a/include/nm-macros-internal.h
+++ b/include/nm-macros-internal.h
@@ -46,6 +46,31 @@
 
 /********************************************************/
 
+/* http://stackoverflow.com/a/2124385/354393 */
+
+#define NM_NARG(...) \
+         _NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N())
+#define _NM_NARG(...) \
+         _NM_NARG_ARG_N(__VA_ARGS__)
+#define _NM_NARG_ARG_N( \
+          _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
+         _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
+         _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
+         _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
+         _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
+         _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
+         _61,_62,_63,N,...) N
+#define _NM_NARG_RSEQ_N() \
+         63,62,61,60,                   \
+         59,58,57,56,55,54,53,52,51,50, \
+         49,48,47,46,45,44,43,42,41,40, \
+         39,38,37,36,35,34,33,32,31,30, \
+         29,28,27,26,25,24,23,22,21,20, \
+         19,18,17,16,15,14,13,12,11,10, \
+         9,8,7,6,5,4,3,2,1,0
+
+/********************************************************/
+
 #if defined (__GNUC__)
 #define _NM_PRAGMA_WARNING_DO(warning)       G_STRINGIFY(GCC diagnostic ignored warning)
 #elif defined (__clang__)
@@ -85,21 +110,68 @@
 /* macro to return strlen() of a compile time string. */
 #define STRLEN(str)     ( sizeof ("" str) - 1 )
 
-#define NM_IN_SET(x, y, ...)                                    \
-    ({                                                          \
-        const typeof(y) _y = (y);                               \
-        typeof(_y) _x = (x);                                    \
-        unsigned _i;                                            \
-        gboolean _found = FALSE;                                \
-        for (_i = 0; _i < 1 + sizeof((typeof(_x)[]) { __VA_ARGS__ })/sizeof(typeof(_x)); _i++) { \
-            if (((typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \
-                _found = TRUE;                                  \
-                break;                                          \
-            }                                                   \
-        }                                                       \
-        _found;                                                 \
+/********************************************************/
+
+#define _NM_IN_SET_EVAL_1(op, x, y1)                              \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_2(op, x, y1, y2)                          \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+         op (_x == (y2))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_3(op, x, y1, y2, y3)                      \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+         op (_x == (y2))                                          \
+         op (_x == (y3))                                          \
+        );                                                        \
     })
 
+#define _NM_IN_SET_EVAL_4(op, x, y1, y2, y3, y4)                  \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+         op (_x == (y2))                                          \
+         op (_x == (y3))                                          \
+         op (_x == (y4))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_5(op, x, y1, y2, y3, y4, y5)              \
+    ({                                                            \
+        typeof(x) _x = (x);                                       \
+        (   (_x == (y1))                                          \
+         op (_x == (y2))                                          \
+         op (_x == (y3))                                          \
+         op (_x == (y4))                                          \
+         op (_x == (y5))                                          \
+        );                                                        \
+    })
+
+#define _NM_IN_SET_EVAL_N2(op, x, n, ...)        _NM_IN_SET_EVAL_##n(op, x, __VA_ARGS__)
+#define _NM_IN_SET_EVAL_N(op, x, n, ...)         _NM_IN_SET_EVAL_N2(op, x, n, __VA_ARGS__)
+
+/* Beware that this does short-circuit evaluation (use "||" instead of "|")
+ * which has a possibly unexpected non-function-like behavior.
+ * Use NM_IN_SET_SE if you need all arguments to be evaluted. */
+#define NM_IN_SET(x, ...)               _NM_IN_SET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
+
+/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do
+ * short-circuit evaluation, which can make a difference if the arguments have
+ * side-effects. */
+#define NM_IN_SET_SE(x, ...)            _NM_IN_SET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__)
+
+/*****************************************************************************/
+
 #define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \
 	(cond) ? (prefix) : "", \
 	(cond) ? (str) : (str_else), \