From 52118baecb0b6e580814db69e52a02c233c633df Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sat, 31 Dec 2022 02:50:59 +0100 Subject: Add the GEHASHMAP_DEF macro --- examples/gehashmap.c | 6 ++--- src/gehashmap.h | 72 +++++++++++++++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/examples/gehashmap.c b/examples/gehashmap.c index 7d6d1a4..17f8eb4 100644 --- a/examples/gehashmap.c +++ b/examples/gehashmap.c @@ -4,10 +4,8 @@ #include -GEHASHMAP_API(char *, int, atoimap) -GEHASHMAP_API(int, unsigned int, itoumap) -GEHASHMAP_IMPL(char *, int, atoimap) -GEHASHMAP_IMPL(int, unsigned int, itoumap) +GEHASHMAP_DEF(char *, int, atoimap) +GEHASHMAP_DEF(int, unsigned int, itoumap) bool atoimap_key_iseq(char *a, char *b) diff --git a/src/gehashmap.h b/src/gehashmap.h index 600666e..17dfdbc 100644 --- a/src/gehashmap.h +++ b/src/gehashmap.h @@ -43,51 +43,59 @@ (entry) = (tmp), \ (tmp) = (entry) ? (entry)->next : NULL) -#define GEHASHMAP_API(k, v, n) \ - struct n##_entry { \ +#define GEHASHMAP_DEF(k, v, n) \ + GEHASHMAP_DEF_API(k, v, n) \ + GEHASHMAP_DEF_IMPL(k, v, n) + +#define GEHASHMAP_DEF_API(k, v, n) \ + GEHASHMAP_DEF_API_HELPER(k, v, n, n##_t, n##_entry) +#define GEHASHMAP_DEF_API_HELPER(k, v, n, n_t, n_e) \ + struct n_e { \ k key; \ v val; \ - struct n##_entry *next; \ + struct n_e *next; \ }; \ \ typedef struct { \ size_t size, \ capacity; \ - struct n##_entry **entries; \ - } n##_t; \ + struct n_e **entries; \ + } n_t; \ \ - void n##_free(n##_t *); \ - bool n##_get(n##_t *, k, v *); \ - bool n##_has(n##_t *, k); \ - int n##_new(n##_t *); \ - int n##_set(n##_t *, k, v); \ - int n##_remove(n##_t *, k); \ - int n##_resize(n##_t *, size_t); \ + void n##_free(n_t *); \ + bool n##_get(n_t *, k, v *); \ + bool n##_has(n_t *, k); \ + int n##_new(n_t *); \ + int n##_set(n_t *, k, v); \ + int n##_remove(n_t *, k); \ + int n##_resize(n_t *, size_t); \ bool n##_key_iseq(k, k); \ size_t n##_key_hash(k); -#define GEHASHMAP_IMPL(k, v, n) \ +#define GEHASHMAP_DEF_IMPL(k, v, n) \ + GEHASHMAP_DEF_IMPL_HELPER(k, v, n, n##_t, n##_entry) +#define GEHASHMAP_DEF_IMPL_HELPER(k, v, n, n_t, n_e) \ /* Function to initialize a new hashmap. Allocation of the hashmap is * left up to the library user. On error -1 is returned, otherwise 0 is * returned. */ \ int \ - n##_new(n##_t *map) \ + n##_new(n_t *map) \ { \ - *map = (n##_t) { \ + *map = (n_t) { \ .size = 0, \ .capacity = GEHASHMAP_INITIAL_SIZE, \ .entries = calloc(GEHASHMAP_INITIAL_SIZE, \ - sizeof(struct n##_entry *)) \ + sizeof(struct n_e *)) \ }; \ return map->entries == NULL ? -1 : 0; \ } \ \ /* Function to destroy a hashmap */ \ void \ - n##_free(n##_t *map) \ + n##_free(n_t *map) \ { \ - struct n##_entry *entry, *tmp; \ + struct n_e *entry, *tmp; \ GEHASHMAP_FOREACH_SAFE(entry, tmp, map) \ free(entry); \ free(map->entries); \ @@ -98,17 +106,17 @@ * otherwise 0 is returned. */ \ int \ - n##_resize(n##_t *map, size_t new_capacity) \ + n##_resize(n_t *map, size_t new_capacity) \ { \ - struct n##_entry **new_entries = \ - calloc(new_capacity, sizeof(struct n##_entry *)); \ + struct n_e **new_entries = \ + calloc(new_capacity, sizeof(struct n_e *)); \ if (new_entries == NULL) \ return -1; \ \ for (size_t i = 0; i < map->capacity; i++) { \ - struct n##_entry *entry = map->entries[i]; \ + struct n_e *entry = map->entries[i]; \ while (entry != NULL) { \ - struct n##_entry *next = entry->next; \ + struct n_e *next = entry->next; \ size_t hash = n##_key_hash(entry->key) \ % new_capacity; \ entry->next = new_entries[hash]; \ @@ -130,10 +138,10 @@ * -1 is returned, otherwise 0 is returned. */ \ int \ - n##_set(n##_t *map, k key, v val) \ + n##_set(n_t *map, k key, v val) \ { \ size_t hash; \ - struct n##_entry *entry; \ + struct n_e *entry; \ \ if (map->size + 1 > map->capacity * GEHASHMAP_LOAD_FACTOR) { \ if (n##_resize(map, map->capacity * 2) == -1) \ @@ -149,7 +157,7 @@ } \ } \ \ - if ((entry = malloc(sizeof(struct n##_entry))) == NULL) \ + if ((entry = malloc(sizeof(struct n_e))) == NULL) \ return -1; \ \ entry->key = key; \ @@ -167,10 +175,10 @@ * returned. */ \ bool \ - n##_get(n##_t *map, k key, v *val) \ + n##_get(n_t *map, k key, v *val) \ { \ size_t hash = n##_key_hash(key) % map->capacity; \ - struct n##_entry *entry = map->entries[hash]; \ + struct n_e *entry = map->entries[hash]; \ \ for (; entry != NULL; entry = entry->next) { \ if (n##_key_iseq(entry->key, key)) { \ @@ -188,7 +196,7 @@ * function that passes NULL as the last argument. */ \ bool \ - n##_has(n##_t *map, k key) \ + n##_has(n_t *map, k key) \ { \ return n##_get(map, key, NULL); \ } \ @@ -198,10 +206,10 @@ * On error -1 is returned, otherwise 0 is returned. */ \ int \ - n##_remove(n##_t *map, k key) \ + n##_remove(n_t *map, k key) \ { \ size_t hash = n##_key_hash(key) % map->capacity; \ - struct n##_entry *entry; \ + struct n_e *entry; \ \ if ((entry = map->entries[hash]) == NULL) \ return -1; \ @@ -215,7 +223,7 @@ \ for (; entry->next != NULL; entry = entry->next) { \ if (n##_key_iseq(entry->next->key, key)) { \ - struct n##_entry *next = entry->next; \ + struct n_e *next = entry->next; \ entry->next = next->next; \ free(next); \ map->size--; \ -- cgit v1.2.3