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))
* 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);
/* 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 *,
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 */
((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