67
67
/* Initializer for an empty hash map. */
68
#define HMAP_INITIALIZER(HMAP) { &(HMAP)->one, NULL, 0, 0 }
68
#define HMAP_INITIALIZER(HMAP) \
69
{ (struct hmap_node **const) &(HMAP)->one, NULL, 0, 0 }
70
71
/* Initialization. */
71
72
void hmap_init(struct hmap *);
116
117
#define HMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HMAP) \
117
118
for (ASSIGN_CONTAINER(NODE, hmap_first_with_hash(HMAP, HASH), MEMBER); \
118
&(NODE)->MEMBER != NULL; \
119
NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \
119
120
ASSIGN_CONTAINER(NODE, hmap_next_with_hash(&(NODE)->MEMBER), \
121
122
#define HMAP_FOR_EACH_IN_BUCKET(NODE, MEMBER, HASH, HMAP) \
122
123
for (ASSIGN_CONTAINER(NODE, hmap_first_in_bucket(HMAP, HASH), MEMBER); \
123
&(NODE)->MEMBER != NULL; \
124
NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \
124
125
ASSIGN_CONTAINER(NODE, hmap_next_in_bucket(&(NODE)->MEMBER), MEMBER))
126
127
static inline struct hmap_node *hmap_first_with_hash(const struct hmap *,
137
138
/* Iterates through every node in HMAP. */
138
139
#define HMAP_FOR_EACH(NODE, MEMBER, HMAP) \
139
140
for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \
140
&(NODE)->MEMBER != NULL; \
141
NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \
141
142
ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER))
143
144
/* Safe when NODE may be freed (not needed when NODE may be removed from the
144
145
* hash map but its members remain accessible and intact). */
145
146
#define HMAP_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HMAP) \
146
147
for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \
147
(&(NODE)->MEMBER != NULL \
148
? ASSIGN_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER) \
148
(NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER) \
149
? ASSIGN_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER), 1 \
152
153
/* Continues an iteration from just after NODE. */
153
154
#define HMAP_FOR_EACH_CONTINUE(NODE, MEMBER, HMAP) \
154
155
for (ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER); \
155
&(NODE)->MEMBER != NULL; \
156
NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER); \
156
157
ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER))
158
159
static inline struct hmap_node *hmap_first(const struct hmap *);