+/* Licensed under LGPLv3+ - see LICENSE file for details */
#ifndef CCAN_FOREACH_H
#define CCAN_FOREACH_H
#include "config.h"
/**
* foreach_int - iterate over a fixed series of integers
* @i: the int-compatible iteration variable
- * @val: one or more integer-compatible values
+ * ...: one or more integer-compatible values
*
* This is a convenient wrapper function for setting a variable to one or
* more explicit values in turn. continue and break work as expected.
* printf("i is %i\n", i);
* }
*/
-#define foreach_int(i, val, ...) \
- for (unsigned _foreach_i = ((i) = val, 0); \
- _foreach_i < sizeof((int[]) { val, __VA_ARGS__ })/sizeof(val); \
- (i) = (int[]) { val, __VA_ARGS__, 0 }[++_foreach_i])
+#define foreach_int(i, ...) \
+ for (unsigned _foreach_i = (((i) = ((int[]) { __VA_ARGS__ })[0]), 0); \
+ _foreach_i < sizeof((int[]) { __VA_ARGS__ })/sizeof(int); \
+ (i) = ((int[]) { __VA_ARGS__, 0 })[++_foreach_i])
/**
* foreach_ptr - iterate over a non-NULL series of pointers
* @i: the pointer iteration variable
- * @val: one or more compatible pointer values
+ * ...: one or more compatible pointer values
*
* This is a convenient wrapper function for setting a variable to one
* or more explicit values in turn. None of the values can be NULL;
* printf("p is %s\n", p);
* }
*/
-#define foreach_ptr(i, val, ...) \
- for (unsigned _foreach_i = (unsigned long)((i) = (val), 0); \
+#define foreach_ptr(i, ...) \
+ for (unsigned _foreach_i \
+ = (((i) = (void *)((FOREACH_TYPEOF(i)[]){ __VA_ARGS__ })[0]), 0); \
(i); \
- (i) = ((FOREACH_TYPEOF(val)[]){(val), __VA_ARGS__, NULL}) \
- [++_foreach_i]) \
+ (i) = (void *)((FOREACH_TYPEOF(i)[]) \
+ { __VA_ARGS__, NULL})[++_foreach_i], \
_foreach_no_nullval(_foreach_i, i, \
- ((void *[]){ val, __VA_ARGS__})))
+ ((const void *[]){ __VA_ARGS__})))
#else /* !HAVE_FOR_LOOP_DECLARATION */
/* GCC in C89 mode still has compound literals, but no for-declarations */
-#define foreach_int(i, val, ...) \
- for ((i) = (val), _foreach_iter_init(&(i)); \
- _foreach_iter(&(i)) < sizeof((int[]) { (val), __VA_ARGS__ }) \
+#define foreach_int(i, ...) \
+ for ((i) = ((int[]){ __VA_ARGS__ })[0], _foreach_iter_init(&(i)); \
+ _foreach_iter(&(i)) < sizeof((int[]) { __VA_ARGS__ }) \
/ sizeof(int); \
- (i) = (int[]) { (val), __VA_ARGS__, 0 }[_foreach_iter_inc(&(i))])
+ (i) = (int[]) { __VA_ARGS__, 0 }[_foreach_iter_inc(&(i))])
-#define foreach_ptr(i, val, ...) \
- for ((i) = (val), _foreach_iter_init(&(i)); \
+#define foreach_ptr(i, ...) \
+ for ((i) = (void *)((FOREACH_TYPEOF(i)[]){ __VA_ARGS__ })[0], \
+ _foreach_iter_init(&(i)); \
(i); \
- (i) = ((FOREACH_TYPEOF(val)[]){ (val), __VA_ARGS__, 0 }) \
+ (i) = (void *)((FOREACH_TYPEOF(i)[]){ __VA_ARGS__, NULL }) \
[_foreach_iter_inc(&(i))], \
_foreach_no_nullval(_foreach_iter(&(i)), i, \
- ((void *[]){ val, __VA_ARGS__})))
+ ((const void *[]){ __VA_ARGS__})))
void _foreach_iter_init(const void *i);
unsigned int _foreach_iter(const void *i);
assert((i) >= sizeof(arr)/sizeof(arr[0]) || (p))
#if HAVE_TYPEOF
-#define FOREACH_TYPEOF(val) __typeof__(&*(val))
+#define FOREACH_TYPEOF(i) __typeof__(i)
#else
-#define FOREACH_TYPEOF(val) void *
+#define FOREACH_TYPEOF(i) const void *
#endif
#else /* !HAVE_COMPOUND_LITERALS */
/* No compound literals, but it's still (just) possible. */
-#define foreach_int(i, val, ...) \
- for (i = _foreach_intval_init(&(i), val, __VA_ARGS__, \
- _foreach_term); \
- !_foreach_intval_done(&i); \
- i = _foreach_intval_next(&(i), val, __VA_ARGS__, \
- _foreach_term))
+#define foreach_int(i, ...) \
+ for (i = _foreach_intval_init(&(i), __VA_ARGS__, _foreach_term); \
+ !_foreach_intval_done(&i); \
+ i = _foreach_intval_next(&(i), __VA_ARGS__, _foreach_term))
-#define foreach_ptr(i, val, ...) \
- for (i = _foreach_ptrval_init(&(i), val, __VA_ARGS__, NULL); \
+#define foreach_ptr(i, ...) \
+ for (i = _foreach_ptrval_init(&(i), __VA_ARGS__, NULL); \
(i); \
- i = _foreach_ptrval_next(&(i), val, __VA_ARGS__, NULL))
+ i = _foreach_ptrval_next(&(i), __VA_ARGS__, NULL))
extern int _foreach_term;
int _foreach_intval_init(const void *i, int val, ...);