summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2022-12-31 02:50:59 +0100
committerThomas Voss <mail@thomasvoss.com> 2022-12-31 02:51:26 +0100
commit52118baecb0b6e580814db69e52a02c233c633df (patch)
treea9c5601d416f1e1e5a58c2077acb7d2abfa7ecf0
parent84c39cf8719ae72870ef8038d7563c0b4e211d0b (diff)
Add the GEHASHMAP_DEF macro
-rw-r--r--examples/gehashmap.c6
-rw-r--r--src/gehashmap.h72
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.h>
-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--; \