diff options
-rw-r--r-- | examples/gehashmap.c | 16 | ||||
-rw-r--r-- | src/gehashmap.h | 32 |
2 files changed, 48 insertions, 0 deletions
diff --git a/examples/gehashmap.c b/examples/gehashmap.c index 1ddd391..df91669 100644 --- a/examples/gehashmap.c +++ b/examples/gehashmap.c @@ -56,6 +56,7 @@ main(void) { int i; unsigned int u; + struct atoimap_entry *entry, *tmp; atoimap_t *map_a; itoumap_t *map_b; @@ -69,6 +70,11 @@ main(void) atoimap_get(map_a, "THOMAS VOẞ", &i); printf("THOMAS VOẞ -> %d\n", i); atoimap_get(map_a, "Thomas Voss", &i); printf("Thomas Voss -> %d\n", i); + GEHASHMAP_FOREACH_SAFE(entry, tmp, map_a) + atoimap_remove(map_a, entry->key); + GEHASHMAP_FOREACH(entry, map_a) + puts(entry->key); + itoumap_set(map_b, -42, +42); itoumap_set(map_b, -69, +69); itoumap_set(map_b, -420, +420); @@ -92,6 +98,16 @@ main(void) atoimap_free(map_a); itoumap_free(map_b); + atoimap_new(map_a); + atoimap_set(map_a, strdup("Thomas Voß"), 5); + atoimap_set(map_a, strdup("THOMAS VOẞ"), 6); + atoimap_set(map_a, strdup("Thomas Voss"), 7); + + GEHASHMAP_FOREACH(entry, map_a) + free(entry->key); + + atoimap_free(map_a); + free(map_a); free(map_b); } diff --git a/src/gehashmap.h b/src/gehashmap.h index 311c2c3..1f24943 100644 --- a/src/gehashmap.h +++ b/src/gehashmap.h @@ -11,6 +11,38 @@ #define GEHASHMAP_INITIAL_SIZE 16 #define GEHASHMAP_LOAD_FACTOR 0.75 +/* The GEHASHMAP_FOREACH() macro takes 2 arguments. The first argument “entry” + * is a “struct n##_entry *”. This variable will be set to point to the next + * hashmap entry each iteration. The second argument “map” is a pointer to the + * hashmap to iterate over. + * + * This macro is unsafe to use when modifying the hashmap inplace (i.e. when + * calling n##_remove() in the loop). + */ +#define GEHASHMAP_FOREACH(entry, map) \ + for (size_t _gehashmap_i = 0; \ + _gehashmap_i < (map)->capacity; \ + (_gehashmap_i)++) \ + for ((entry) = (map)->entries[_gehashmap_i]; \ + (entry) != NULL; \ + (entry) = (entry)->next) + +/* The GEHASHMAP_FOREACH_SAFE() macro is identical to the GEHASHMAP_FOREACH() + * macro except it takes an additional “tmp” argument. This argument is of the + * same type as “entry” (a “struct n##_entry *”) and shouldn’t be interacted + * with by the library user. This macro allows you to modify the hashmap + * inplace while iterating. + */ +#define GEHASHMAP_FOREACH_SAFE(entry, tmp, map) \ + for (size_t _gehashmap_i = 0; \ + _gehashmap_i < (map)->capacity; \ + (_gehashmap_i)++) \ + for ((entry) = (map)->entries[_gehashmap_i], \ + (tmp) = (entry) ? (entry)->next : NULL; \ + (entry) != NULL; \ + (entry) = (tmp), \ + (tmp) = (entry) ? (entry)->next : NULL) + #define GEHASHMAP_API(k, v, n) \ struct n##_entry { \ k key; \ |