diff --git a/src/cmc/deque.h b/src/cmc/deque.h index ecbf4ae..54d52f5 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -39,18 +39,6 @@ /* ------------------------------------------------------------------------- * Deque Specific * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_deque = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "front:%" PRIuMAX ", " - "back:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; /** * Core Deque implementation diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 16b716a..2127ab8 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -29,22 +29,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/hashtable.h" -/* ------------------------------------------------------------------------- - * HashMap Specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_key:%p, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core HashMap implementation */ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 06cec26..b868dff 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -18,6 +18,19 @@ */ #define CMC_EXT_CMC_DEQUE_PARTS INIT, ITER, STR +/* Used by STR */ +static const char *cmc_cmc_string_fmt_deque = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "front:%" PRIuMAX ", " + "back:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; + /** * INIT * diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 9c462ae..76d679b 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -18,6 +18,19 @@ */ #define CMC_EXT_CMC_HASHMAP_PARTS INIT, STR +/* Used by STR */ +static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; + /** * INIT * @@ -28,15 +41,17 @@ CMC_EXT_CMC_HASHMAP_INIT_HEADER(BODY) \ CMC_EXT_CMC_HASHMAP_INIT_SOURCE(BODY) -#define CMC_EXT_CMC_HASHMAP_INIT_HEADER(BODY) \ - CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMAP_INIT_HEADER(BODY) \ + CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE(BODY) \ - CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE(BODY) \ + CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(PFX, SNAME, V) \ +#define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(PFX, SNAME, K, V) \ \ struct SNAME CMC_(PFX, _init)(size_t capacity, double load, \ struct CMC_DEF_FKEY(SNAME) * f_key, \ @@ -46,55 +61,55 @@ struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ struct cmc_callbacks * callbacks); -#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, V) \ - \ - struct SNAME CMC_(PFX, _init)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _init_custom)(capacity, load, f_key, f_val, NULL, \ - NULL); \ - } \ - \ - struct SNAME CMC_(PFX, _init_custom)( \ - size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - struct SNAME _map_ = { 0 }; \ - \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return _map_; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return _map_; \ - \ - if (!f_key || !f_val) \ - return _map_; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - _map_.buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \ - \ - if (!_map_.buffer) \ - return _map_; \ - \ - _map_.count = 0; \ - _map_.capacity = real_capacity; \ - _map_.load = load; \ - _map_.flag = CMC_FLAG_OK; \ - _map_.f_key = f_key; \ - _map_.f_val = f_val; \ - _map_.alloc = alloc; \ - _map_.callbacks = callbacks; \ - \ - return _map_; \ +#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, K, V) \ + \ + struct SNAME CMC_(PFX, _init)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _init_custom)(capacity, load, f_key, f_val, NULL, \ + NULL); \ + } \ + \ + struct SNAME CMC_(PFX, _init_custom)( \ + size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + struct SNAME _map_ = { 0 }; \ + \ + if (capacity == 0 || load <= 0 || load >= 1) \ + return _map_; \ + \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return _map_; \ + \ + if (!f_key || !f_val) \ + return _map_; \ + \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + _map_.buffer = \ + alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ + \ + if (!_map_.buffer) \ + return _map_; \ + \ + _map_.count = 0; \ + _map_.capacity = real_capacity; \ + _map_.load = load; \ + _map_.flag = CMC_FLAG_OK; \ + _map_.f_key = f_key; \ + _map_.f_val = f_val; \ + _map_.alloc = alloc; \ + _map_.callbacks = callbacks; \ + \ + return _map_; \ } /** @@ -107,69 +122,74 @@ CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \ CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY) -#define CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \ - CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY) \ - CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY) \ + CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, V) \ +#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, K, V) \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_, \ - FILE * fptr); \ + bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \ const char *start, const char *separator, \ - const char *end) + const char *end, const char *key_val_sep); -#define CMC_EXT_CMC_HASHMAP_STR_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ - { \ - struct SNAME *m_ = _map_; \ - \ - return 0 <= fprintf(fptr, cmc_string_len, cmc_cmc_string_fmt_hashmap, \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(K), \ - CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, \ - m_->f_val, m_->alloc, m_->callbacks); \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \ - const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ - \ - size_t last = 0; \ - for (size_t i = _map_->capacity; i > 0; i--) \ - { \ - if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ - \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_map_->f_key->str(fptr, entry->key) || \ - !_map_->f_val->str(fptr, entry->value)) \ - return false; \ - } \ - \ - if (i + 1 < last) \ - fprintf(fptr, "%s", separator); \ - } \ - \ - fprintf(fptr, "%s", end); \ - \ - return true; \ +#define CMC_EXT_CMC_HASHMAP_STR_SOURCE_(PFX, SNAME, K, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ + { \ + struct SNAME *m_ = _map_; \ + \ + return 0 <= fprintf(fptr, cmc_cmc_string_fmt_hashmap, \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(K), \ + CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \ + m_->count, m_->load, m_->flag, m_->f_key, \ + m_->f_val, m_->alloc, m_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end, const char *key_val_sep) \ + { \ + fprintf(fptr, "%s", start); \ + \ + size_t last = 0; \ + for (size_t i = _map_->capacity; i > 0; i--) \ + { \ + if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ + \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \ + \ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (!_map_->f_key->str(fptr, entry->key)) \ + return false; \ + \ + fprintf(fptr, "%s", key_val_sep); \ + \ + if (!_map_->f_val->str(fptr, entry->value)) \ + return false; \ + \ + if (i + 1 < last) \ + fprintf(fptr, "%s", separator); \ + } \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ } #endif /* CMC_EXT_CMC_HASHMAP_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 51495da..2364541 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -77,7 +77,7 @@ /* Gets the macro with all EXT parts of a collection */ #define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \ - CMC_EXT_##LIB##_##COLLECTION##_PARTS + CMC_EXT_##LIB##_##COLLECTION##_PARTS, /** * A __VA_ARGS__ argument counter. This argument counter is slightly shifted: diff --git a/tests/to_string.c b/tests/to_string.c index 42aae05..5794037 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -1,84 +1,47 @@ // A visual check for to_string methods -#include "../src/macro_collections.h" +#include "macro_collections.h" -CMC_COLLECTION_GENERATE(BIDIMAP, bm, bmap, int, int) -CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int) -CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int) -CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int) -CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* K */, int) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int) -CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int) -CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int) -CMC_COLLECTION_GENERATE(MULTISET, ms, mset, /* K */, int) -CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl, slist, /* K */, int) -CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int) -CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int) -CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int) +// clang-format off +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) + +struct +{ + CMC_DEF_FTAB_CMP(int); + CMC_DEF_FTAB_CPY(int); + CMC_DEF_FTAB_STR(int); + CMC_DEF_FTAB_FREE(int); + CMC_DEF_FTAB_HASH(int); + CMC_DEF_FTAB_PRI(int); +} int_ftab = {cmc_i32_cmp, NULL, cmc_i32_str, NULL, cmc_i32_hash, cmc_i32_cmp}; int main(void) { - struct bmap *bm = bm_new_custom(100, 0.7, &(struct bmap_ftab_key){ 0 }, - &(struct bmap_ftab_val){ 0 }, NULL, NULL); - struct deque *d = - d_new_custom(100, &(struct deque_ftab_val){ 0 }, NULL, NULL); - struct hmap *hm = hm_new_custom(100, 0.6, &(struct hmap_ftab_key){ 0 }, - &(struct hmap_ftab_val){ 0 }, NULL, NULL); - struct hset *hs = - hs_new_custom(100, 0.6, &(struct hset_ftab_val){ 0 }, NULL, NULL); - struct heap *h = h_new_custom(100, cmc_max_heap, - &(struct heap_ftab_val){ 0 }, NULL, NULL); - struct iheap *ih = - ih_new_custom(100, &(struct iheap_ftab_val){ 0 }, NULL, NULL); - struct linked *ll = - ll_new_custom(&(struct linked_ftab_val){ 0 }, NULL, NULL); - struct list *l = - l_new_custom(100, &(struct list_ftab_val){ 0 }, NULL, NULL); - struct mmap *mm = mm_new_custom(100, 0.8, &(struct mmap_ftab_key){ 0 }, - &(struct mmap_ftab_val){ 0 }, NULL, NULL); - struct mset *ms = - ms_new_custom(100, 0.6, &(struct mset_ftab_val){ 0 }, NULL, NULL); - struct queue *q = - q_new_custom(100, &(struct queue_ftab_val){ 0 }, NULL, NULL); - struct slist *sl = - sl_new_custom(100, &(struct slist_ftab_val){ 0 }, NULL, NULL); - struct stack *s = - s_new_custom(100, &(struct stack_ftab_val){ 0 }, NULL, NULL); - struct tmap *tm = tm_new_custom(&(struct tmap_ftab_key){ 0 }, - &(struct tmap_ftab_val){ 0 }, NULL, NULL); - struct tset *ts = ts_new_custom(&(struct tset_ftab_val){ 0 }, NULL, NULL); + struct deque *d = d_new(100, (struct deque_fval *)&int_ftab); + struct hashmap *hm = hm_new(100, 0.6, (struct hashmap_fkey *)&int_ftab, + (struct hashmap_fval *)&int_ftab); - printf("%s\n", bm_to_string(bm).s); - printf("%s\n", d_to_string(d).s); - printf("%s\n", hm_to_string(hm).s); - printf("%s\n", hs_to_string(hs).s); - printf("%s\n", h_to_string(h).s); - printf("%s\n", ih_to_string(ih).s); - printf("%s\n", ll_to_string(ll).s); - printf("%s\n", l_to_string(l).s); - printf("%s\n", mm_to_string(mm).s); - printf("%s\n", ms_to_string(ms).s); - printf("%s\n", q_to_string(q).s); - printf("%s\n", sl_to_string(sl).s); - printf("%s\n", s_to_string(s).s); - printf("%s\n", tm_to_string(tm).s); - printf("%s\n", ts_to_string(ts).s); + d_to_string(d, stdout); + d_print(d, stdout, "\n[ ", ", ", " ]\n"); + hm_to_string(hm, stdout); + hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + + for (int i = 0; i < 20; i++) + { + d_push_back(d, i); + hm_insert(hm, i, i); + } + + fprintf(stdout, "\n"); + + d_to_string(d, stdout); + d_print(d, stdout, "\n[ ", ", ", " ]\n"); + hm_to_string(hm, stdout); + hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - bm_free(bm); d_free(d); hm_free(hm); - hs_free(hs); - h_free(h); - ih_free(ih); - ll_free(ll); - l_free(l); - mm_free(mm); - ms_free(ms); - q_free(q); - sl_free(sl); - s_free(s); - tm_free(tm); - ts_free(ts); } + +// clang-format on