#ifndef LIBGE_GESET_H #define LIBGE_GESET_H #include #include #define GESET_FOREACH(n, t, e, s) \ for (size_t __ge_i = 0; __ge_i < (s).__cap; __ge_i++) \ for (struct __##n##_hashmap_entry *__ge_e = (s).__ents[__ge_i]; \ __ge_e != NULL; \ __ge_e = __ge_e->__next) \ for (bool __ge_c = true; __ge_c; __ge_c = false) \ for (t e = __ge_e->key; __ge_c; __ge_c = false) #define GESET_FOREACH_SAFE(n, t, e, s) \ for (size_t __ge_i = 0; __ge_i < (s).__cap; __ge_i++) \ for (struct __##n##_hashmap_entry *__ge_e = (s).__ents[__ge_i], \ *__ge_t = __ge_e ? __ge_e->__next : NULL; \ __ge_e != NULL; \ __ge_e = __ge_t, __ge_t = __ge_e ? __ge_e->__next : NULL) \ for (bool __ge_c = true; __ge_c; __ge_c = false) \ for (t e = __ge_e->key; __ge_c; __ge_c = false) #define GESET_DEF(t, n) \ GESET_DEF_API(t, n) \ GESET_DEF_IMPL(t, n) #define GESET_DEF_API(t, n) \ GESET_DEF_API_HELPER(t, n, n##_t, __##n##_hashmap) #define GESET_DEF_API_HELPER(t, n, n_t, int_n) \ GEHASHMAP_DEF_API(t, int, int_n) \ \ typedef int_n##_t n_t; \ \ int n##_new(n_t *, size_t, double); \ void n##_free(n_t *); \ int n##_add(n_t *, t); \ bool n##_has(n_t *, t); \ size_t n##_size(n_t *); \ bool n##_empty(n_t *); \ bool n##_intersects(n_t *, n_t *); \ int n##_remove(n_t *, t); \ int n##_resize(n_t *, size_t); \ bool int_n##_key_iseq(t, t); \ size_t int_n##_key_hash(t); \ bool n##_elem_iseq(t, t); \ size_t n##_elem_hash(t); #define GESET_DEF_IMPL(t, n) \ GESET_DEF_IMPL_HELPER(t, n, n##_t, __##n##_hashmap) #define GESET_DEF_IMPL_HELPER(t, n, n_t, int_n) \ GEHASHMAP_DEF_IMPL(t, int, int_n) \ \ bool \ int_n##_key_iseq(t a, t b) \ { \ return n##_elem_iseq(a, b); \ } \ \ size_t \ int_n##_key_hash(t e) \ { \ return n##_elem_hash(e); \ } \ \ int \ n##_new(n_t *set, size_t cap, double loadf) \ { \ return int_n##_new(set, cap, loadf); \ } \ \ void \ n##_free(n_t *set) \ { \ int_n##_free(set); \ } \ \ int \ n##_add(n_t *set, t e) \ { \ return int_n##_set(set, e, 0); \ } \ \ bool \ n##_has(n_t *set, t e) \ { \ return int_n##_has(set, e); \ } \ \ size_t \ n##_size(n_t *set) \ { \ return int_n##_size(set); \ } \ \ bool \ n##_empty(n_t *set) \ { \ return int_n##_empty(set); \ } \ \ bool \ n##_intersects(n_t *a, n_t *b) \ { \ GESET_FOREACH(n, t, e, *a) { \ if (n##_has(b, e)) \ return true; \ } \ return false; \ } \ \ int \ n##_remove(n_t *set, t e) \ { \ return int_n##_remove(set, e); \ } \ \ int \ n##_resize(n_t *set, size_t ncap) \ { \ return int_n##_resize(set, ncap); \ } #endif /* !LIBGE_GESET_H */