-/* Iteration.
- *
- * The _SAFE version is needed when NODE may be freed. It is not needed when
- * NODE may be removed from the hash map but its members remain accessible and
- * intact. */
-#define HMAP_FOR_EACH(NODE, STRUCT, MEMBER, HMAP) \
- for ((NODE) = CONTAINER_OF(hmap_first(HMAP), STRUCT, MEMBER); \
- &(NODE)->MEMBER != NULL; \
- (NODE) = CONTAINER_OF(hmap_next(HMAP, &(NODE)->MEMBER), \
- STRUCT, MEMBER))
-
-#define HMAP_FOR_EACH_SAFE(NODE, NEXT, STRUCT, MEMBER, HMAP) \
- for ((NODE) = CONTAINER_OF(hmap_first(HMAP), STRUCT, MEMBER); \
- (&(NODE)->MEMBER != NULL \
- ? (NEXT) = CONTAINER_OF(hmap_next(HMAP, &(NODE)->MEMBER), \
- STRUCT, MEMBER), 1 \
- : 0); \
+bool hmap_contains(const struct hmap *, const struct hmap_node *);
+
+/* Iteration. */
+
+/* Iterates through every node in HMAP. */
+#define HMAP_FOR_EACH(NODE, MEMBER, HMAP) \
+ for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \
+ NODE != OBJECT_CONTAINING(NULL, 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 (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \
+ (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER) \
+ ? ASSIGN_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER), 1 \
+ : 0); \