@@ -134,17 +134,17 @@ struct hmap_node *hmap_random_node(const struct hmap *);
* without using 'break', NODE will be NULL. This is true for all of the
* HMAP_FOR_EACH_*() macros.
*/
-#define HMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HMAP) \
- for (INIT_CONTAINER(NODE, hmap_first_with_hash(HMAP, HASH), MEMBER); \
- (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \
- || ((NODE = NULL), false); \
- ASSIGN_CONTAINER(NODE, hmap_next_with_hash(&(NODE)->MEMBER), \
- MEMBER))
-#define HMAP_FOR_EACH_IN_BUCKET(NODE, MEMBER, HASH, HMAP) \
- for (INIT_CONTAINER(NODE, hmap_first_in_bucket(HMAP, HASH), MEMBER); \
- (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \
- || ((NODE = NULL), false); \
- ASSIGN_CONTAINER(NODE, hmap_next_in_bucket(&(NODE)->MEMBER), MEMBER))
+#define HMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HMAP) \
+ for (INIT_MULTIVAR(NODE, MEMBER, hmap_first_with_hash(HMAP, HASH)); \
+ CONDITION_MULTIVAR(ITER_VAR(NODE) != NULL, NODE, MEMBER); \
+ UPDATE_MULTIVAR(ITER_VAR(NODE) = hmap_next_with_hash(ITER_VAR(NODE)),\
+ NODE))
+
+#define HMAP_FOR_EACH_IN_BUCKET(NODE, MEMBER, HASH, HMAP) \
+ for (INIT_MULTIVAR(NODE, MEMBER, hmap_first_in_bucket(HMAP, HASH)); \
+ CONDITION_MULTIVAR(ITER_VAR(NODE) != NULL, NODE, MEMBER); \
+ UPDATE_MULTIVAR(ITER_VAR(NODE) = hmap_next_in_bucket(ITER_VAR(NODE)),\
+ NODE))
static inline struct hmap_node *hmap_first_with_hash(const struct hmap *,
size_t hash);
@@ -170,33 +170,34 @@ bool hmap_contains(const struct hmap *, const struct hmap_node *);
/* Iterates through every node in HMAP. */
#define HMAP_FOR_EACH(NODE, MEMBER, HMAP) \
HMAP_FOR_EACH_INIT(NODE, MEMBER, HMAP, (void) 0)
-#define HMAP_FOR_EACH_INIT(NODE, MEMBER, HMAP, ...) \
- for (INIT_CONTAINER(NODE, hmap_first(HMAP), MEMBER), __VA_ARGS__; \
- (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \
- || ((NODE = NULL), false); \
- ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER))
+#define HMAP_FOR_EACH_INIT(NODE, MEMBER, HMAP, ...) \
+ for (INIT_MULTIVAR_EXP(NODE, MEMBER, hmap_first(HMAP), __VA_ARGS__); \
+ CONDITION_MULTIVAR(ITER_VAR(NODE) != NULL, NODE, MEMBER); \
+ UPDATE_MULTIVAR(ITER_VAR(NODE) = hmap_next(HMAP, ITER_VAR(NODE)), \
+ NODE))
/* Safe when NODE may be freed (not needed when NODE may be removed from the
* hash map but its members remain accessible and intact). */
#define HMAP_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HMAP) \
- HMAP_FOR_EACH_SAFE_INIT(NODE, NEXT, MEMBER, HMAP, (void) 0)
-#define HMAP_FOR_EACH_SAFE_INIT(NODE, NEXT, MEMBER, HMAP, ...) \
- for (INIT_CONTAINER(NODE, hmap_first(HMAP), MEMBER), __VA_ARGS__; \
- ((NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \
- || ((NODE = NULL), false) \
- ? INIT_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER), 1 \
- : 0); \
- (NODE) = (NEXT))
+ HMAP_FOR_EACH_SAFE_INIT(NODE, NEXT, MEMBER, HMAP, (void) NEXT)
+#define HMAP_FOR_EACH_SAFE_INIT(NODE, NEXT, MEMBER, HMAP, ...) \
+ for (INIT_MULTIVAR_SAFE_EXP(NODE, MEMBER, hmap_first(HMAP), (void) NEXT, \
+ __VA_ARGS__); \
+ CONDITION_MULTIVAR_SAFE(ITER_VAR(NODE) != NULL, \
+ ITER_NEXT_VAR(NODE) = hmap_next(HMAP, ITER_VAR(NODE)),\
+ NODE, MEMBER); \
+ UPDATE_MULTIVAR_SAFE(NODE))
/* Continues an iteration from just after NODE. */
#define HMAP_FOR_EACH_CONTINUE(NODE, MEMBER, HMAP) \
HMAP_FOR_EACH_CONTINUE_INIT(NODE, MEMBER, HMAP, (void) 0)
-#define HMAP_FOR_EACH_CONTINUE_INIT(NODE, MEMBER, HMAP, ...) \
- for (ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER), \
- __VA_ARGS__; \
- (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \
- || ((NODE = NULL), false); \
- ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER))
+#define HMAP_FOR_EACH_CONTINUE_INIT(NODE, MEMBER, HMAP, ...) \
+ for (INIT_MULTIVAR_EXP(NODE, MEMBER, hmap_next(HMAP, &(NODE)->MEMBER), \
+ __VA_ARGS__); \
+ CONDITION_MULTIVAR(ITER_VAR(NODE) != NULL, NODE, MEMBER); \
+ UPDATE_MULTIVAR(ITER_VAR(NODE) = hmap_next(HMAP, ITER_VAR(NODE)), \
+ NODE))
+
static inline struct hmap_node *
hmap_pop_helper__(struct hmap *hmap, size_t *bucket) {
Rewrite hmap's loops using multi-variable helpers. For safe loops, we keep the (now unused) NEXT variable to keep backwards compatibility. Signed-off-by: Adrian Moreno <amorenoz@redhat.com> --- include/openvswitch/hmap.h | 61 +++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 30 deletions(-)