util: Introduce ASSIGN_CONTAINER to make iteration macros easier to read.
authorBen Pfaff <blp@nicira.com>
Wed, 17 Nov 2010 22:25:33 +0000 (14:25 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 6 Dec 2010 17:59:30 +0000 (09:59 -0800)
lib/classifier.h
lib/hmap.h
lib/list.h
lib/util.h

index 5629fc0204029c8d4ced05a19edc9085cf719f03..76a3a5c029358ace5a3b3e1cfea9bfbeeb0146df 100644 (file)
@@ -135,20 +135,16 @@ struct cls_rule *cls_cursor_first(struct cls_cursor *);
 struct cls_rule *cls_cursor_next(struct cls_cursor *, struct cls_rule *);
 
 #define CLS_CURSOR_FOR_EACH(RULE, MEMBER, CURSOR)                       \
-    for ((RULE) = OBJECT_CONTAINING(cls_cursor_first(CURSOR),           \
-                                    RULE, MEMBER);                      \
+    for (ASSIGN_CONTAINER(RULE, cls_cursor_first(CURSOR), MEMBER);      \
          &(RULE)->MEMBER != NULL;                                       \
-         (RULE) = OBJECT_CONTAINING(cls_cursor_next(CURSOR,             \
-                                                    &(RULE)->MEMBER),   \
-                                    RULE, MEMBER))
+         ASSIGN_CONTAINER(RULE, cls_cursor_next(CURSOR, &(RULE)->MEMBER), \
+                          MEMBER))
 
 #define CLS_CURSOR_FOR_EACH_SAFE(RULE, NEXT, MEMBER, CURSOR)            \
-    for ((RULE) = OBJECT_CONTAINING(cls_cursor_first(CURSOR),           \
-                                    RULE, MEMBER);                      \
+    for (ASSIGN_CONTAINER(RULE, cls_cursor_first(CURSOR), MEMBER);      \
          (&(RULE)->MEMBER != NULL                                       \
-          ? ((NEXT) = OBJECT_CONTAINING(cls_cursor_next(CURSOR,         \
-                                                        &(RULE)->MEMBER), \
-                                        RULE, MEMBER), 1)               \
+          ? ASSIGN_CONTAINER(NEXT, cls_cursor_next(CURSOR, &(RULE)->MEMBER), \
+                             MEMBER)                                    \
           : 0);                                                         \
          (RULE) = (NEXT))
 
index 674c6c778d2060a835fa98dc47c35db9fca725b3..f6d2827406845ab83ac39c770bc4b877a1935ac9 100644 (file)
@@ -114,17 +114,14 @@ struct hmap_node *hmap_random_node(const struct hmap *);
  * HASH is only evaluated once.
  */
 #define HMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HMAP)               \
-    for ((NODE) = OBJECT_CONTAINING(hmap_first_with_hash(HMAP, HASH),   \
-                                  NODE, MEMBER);                        \
+    for (ASSIGN_CONTAINER(NODE, hmap_first_with_hash(HMAP, HASH), MEMBER); \
          &(NODE)->MEMBER != NULL;                                       \
-         (NODE) = OBJECT_CONTAINING(hmap_next_with_hash(&(NODE)->MEMBER), \
-                                  NODE, MEMBER))
+         ASSIGN_CONTAINER(NODE, hmap_next_with_hash(&(NODE)->MEMBER),   \
+                          MEMBER))
 #define HMAP_FOR_EACH_IN_BUCKET(NODE, MEMBER, HASH, HMAP)               \
-    for ((NODE) = OBJECT_CONTAINING(hmap_first_in_bucket(HMAP, HASH),   \
-                                  NODE, MEMBER);                        \
+    for (ASSIGN_CONTAINER(NODE, hmap_first_in_bucket(HMAP, HASH), MEMBER); \
          &(NODE)->MEMBER != NULL;                                       \
-         (NODE) = OBJECT_CONTAINING(hmap_next_in_bucket(&(NODE)->MEMBER), \
-                               NODE, MEMBER))
+         ASSIGN_CONTAINER(NODE, hmap_next_in_bucket(&(NODE)->MEMBER), MEMBER))
 
 static inline struct hmap_node *hmap_first_with_hash(const struct hmap *,
                                                      size_t hash);
@@ -137,28 +134,24 @@ static inline struct hmap_node *hmap_next_in_bucket(const struct hmap_node *);
 
 /* Iterates through every node in HMAP. */
 #define HMAP_FOR_EACH(NODE, MEMBER, HMAP)                               \
-    for ((NODE) = OBJECT_CONTAINING(hmap_first(HMAP), NODE, MEMBER);    \
+    for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER);              \
          &(NODE)->MEMBER != NULL;                                       \
-         (NODE) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER),   \
-                                    NODE, MEMBER))
+         ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER))
 
 /* 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)                    \
-    for ((NODE) = OBJECT_CONTAINING(hmap_first(HMAP), NODE, MEMBER);    \
+    for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER);              \
          (&(NODE)->MEMBER != NULL                                       \
-          ? (NEXT) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER), \
-                                       NODE, MEMBER), 1                 \
+          ? ASSIGN_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER) \
           : 0);                                                         \
          (NODE) = (NEXT))
 
 /* Continues an iteration from just after NODE. */
 #define HMAP_FOR_EACH_CONTINUE(NODE, MEMBER, HMAP)                      \
-    for ((NODE) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER),   \
-                                    NODE, MEMBER);                      \
+    for (ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER); \
          &(NODE)->MEMBER != NULL;                                       \
-         (NODE) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER),   \
-                                    NODE, MEMBER))
+         ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER))
 
 static inline struct hmap_node *hmap_first(const struct hmap *);
 static inline struct hmap_node *hmap_next(const struct hmap *,
index 0481477ae0934a4f32c6302e6282a25137f94811..013f0488240ad7c9b6fa47ef795ae2351ce35a1f 100644 (file)
@@ -54,17 +54,18 @@ size_t list_size(const struct list *);
 bool list_is_empty(const struct list *);
 
 #define LIST_FOR_EACH(ITER, MEMBER, LIST)                               \
-    for (ITER = OBJECT_CONTAINING((LIST)->next, ITER, MEMBER);          \
+    for (ASSIGN_CONTAINER(ITER, (LIST)->next, MEMBER);                  \
          &(ITER)->MEMBER != (LIST);                                     \
-         ITER = OBJECT_CONTAINING((ITER)->MEMBER.next, ITER, MEMBER))
+         ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.next, MEMBER))
 #define LIST_FOR_EACH_REVERSE(ITER, MEMBER, LIST)                       \
-    for (ITER = OBJECT_CONTAINING((LIST)->prev, ITER, MEMBER);          \
+    for (ASSIGN_CONTAINER(ITER, (LIST)->prev, MEMBER);                  \
          &(ITER)->MEMBER != (LIST);                                     \
-         ITER = OBJECT_CONTAINING((ITER)->MEMBER.prev, ITER, MEMBER))
-#define LIST_FOR_EACH_SAFE(ITER, NEXT, MEMBER, LIST)                    \
-    for (ITER = OBJECT_CONTAINING((LIST)->next, ITER, MEMBER);          \
-         (NEXT = OBJECT_CONTAINING((ITER)->MEMBER.next, ITER, MEMBER),  \
-          &(ITER)->MEMBER != (LIST));                                   \
-         ITER = NEXT)
+         ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.prev, MEMBER))
+#define LIST_FOR_EACH_SAFE(ITER, NEXT, MEMBER, LIST)            \
+    for (ASSIGN_CONTAINER(ITER, (LIST)->next, MEMBER);          \
+         (&(ITER)->MEMBER != (LIST)                             \
+          ? ASSIGN_CONTAINER(NEXT, (ITER)->MEMBER.next, MEMBER) \
+          : 0);                                                 \
+         (ITER) = (NEXT))
 
 #endif /* list.h */
index 29e212dc52cc9d1e6194f637d46f48635fd5c629..49790490614b3d773d014d36abac69fc0da68bbe 100644 (file)
@@ -101,6 +101,14 @@ extern const char *program_name;
     ((OVS_TYPEOF(OBJECT)) (void *)                                      \
      ((char *) (POINTER) - ((char *) &(OBJECT)->MEMBER - (char *) (OBJECT))))
 
+/* Given POINTER, the address of the given MEMBER within an object of the type
+ * that that OBJECT points to, assigns the address of the outer object to
+ * OBJECT, which must be an lvalue.
+ *
+ * Evaluates to 1. */
+#define ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER) \
+    ((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), 1)
+
 #ifdef  __cplusplus
 extern "C" {
 #endif