From a9661c348560cc559a03e6165926be626fc33aa6 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sun, 24 May 2020 13:40:54 -0300 Subject: [PATCH 01/51] Updating cor include guards and separating things from core.h --- src/cor/alloc.h | 30 ++++++++++++++++++++++++++++++ src/cor/callbacks.h | 33 +++++++++++++++++++++++++++++++++ src/cor/core.h | 41 +++++------------------------------------ src/cor/flags.h | 6 +++--- src/cor/hashtable.h | 6 +++--- 5 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 src/cor/alloc.h create mode 100644 src/cor/callbacks.h diff --git a/src/cor/alloc.h b/src/cor/alloc.h new file mode 100644 index 0000000..734c34e --- /dev/null +++ b/src/cor/alloc.h @@ -0,0 +1,30 @@ +/** + * alloc.h + * + * Creation Date: 24/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_COR_ALLOC_H +#define CMC_COR_ALLOC_H + +#include + +/** + * struct cmc_alloc_node + * + * Custom allocation node. Allows collections to use custom allocation + * functions. + */ +static struct cmc_alloc_node +{ + void *(*malloc)(size_t); + void *(*calloc)(size_t, size_t); + void *(*realloc)(void *, size_t); + void (*free)(void *); +} cmc_alloc_node_default = { malloc, calloc, realloc, free }; + +#endif /* CMC_COR_ALLOC_H */ diff --git a/src/cor/callbacks.h b/src/cor/callbacks.h new file mode 100644 index 0000000..613eccc --- /dev/null +++ b/src/cor/callbacks.h @@ -0,0 +1,33 @@ +/** + * callbacks.h + * + * Creation Date: 24/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_COR_CALLBACK_H +#define CMC_COR_CALLBACK_H + +/** + * struct cmc_callbacks + * + * Callback node. Each collection will call one of these functions when: + * - create : an element was successfully added to the collection + * - read : the collection was successfully queried about an element + * - update : an element in the collection was successfully updated + * - delete : an element was successfully removed from the collection + * - resize : the collection was full and successfully resized + */ +struct cmc_callbacks +{ + void (*create)(void); + void (*read)(void); + void (*update)(void); + void (*delete)(void); + void (*resize)(void); +}; + +#endif /* CMC_COR_CALLBACK_H */ diff --git a/src/cor/core.h b/src/cor/core.h index 16ba3c6..e63219b 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -18,8 +18,8 @@ * cmc_flags */ -#ifndef CMC_CORE_H -#define CMC_CORE_H +#ifndef CMC_COR_CORE_H +#define CMC_COR_CORE_H #include #include @@ -28,6 +28,8 @@ #include #include +#include "alloc.h" +#include "callbacks.h" #include "flags.h" #define CMC_TO_STRING_(X) #X @@ -45,37 +47,4 @@ struct cmc_string static const size_t cmc_string_len = 400; -/** - * struct cmc_alloc_node - * - * Custom allocation node. Allows collections to use custom allocation - * functions. - */ -static struct cmc_alloc_node -{ - void *(*malloc)(size_t); - void *(*calloc)(size_t, size_t); - void *(*realloc)(void *, size_t); - void (*free)(void *); -} cmc_alloc_node_default = { malloc, calloc, realloc, free }; - -/** - * struct cmc_callbacks - * - * Callback node. Each collection will call one of these functions when: - * - create : an element was successfully added to the collection - * - read : the collection was successfully queried about an element - * - update : an element in the collection was successfully updated - * - delete : an element was successfully removed from the collection - * - resize : the collection was full and successfully resized - */ -struct cmc_callbacks -{ - void (*create)(void); - void (*read)(void); - void (*update)(void); - void (*delete)(void); - void (*resize)(void); -}; - -#endif /* CMC_CORE_H */ +#endif /* CMC_COR_CORE_H */ diff --git a/src/cor/flags.h b/src/cor/flags.h index da41a0b..e007623 100644 --- a/src/cor/flags.h +++ b/src/cor/flags.h @@ -8,8 +8,8 @@ * */ -#ifndef CMC_FLAGS_H -#define CMC_FLAGS_H +#ifndef CMC_COR_FLAGS_H +#define CMC_COR_FLAGS_H /** * cmc_flags @@ -40,4 +40,4 @@ const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY", "DUPLICATE", "ERROR", "THREAD", "MUTEX" }; -#endif /* CMC_FLAGS_H */ +#endif /* CMC_COR_FLAGS_H */ diff --git a/src/cor/hashtable.h b/src/cor/hashtable.h index 877a1e5..d44fc51 100644 --- a/src/cor/hashtable.h +++ b/src/cor/hashtable.h @@ -12,8 +12,8 @@ * Things commonly used by hashtable-based collections. */ -#ifndef CMC_IMPL_HASHTABLE_H -#define CMC_IMPL_HASHTABLE_H +#ifndef CMC_COR_HASHTABLE_H +#define CMC_COR_HASHTABLE_H #include "core.h" @@ -83,4 +83,4 @@ static const size_t cmc_hashtable_primes[] = { }; // clang-format on -#endif /* CMC_IMPL_HASHTABLE_H */ +#endif /* CMC_COR_HASHTABLE_H */ From ab776dd7f39ba5a86435439a7c448fa0bcefb63f Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 25 May 2020 22:08:05 -0300 Subject: [PATCH 02/51] Added ./cor/params.h --- src/cor/params.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/cor/params.h diff --git a/src/cor/params.h b/src/cor/params.h new file mode 100644 index 0000000..61d6091 --- /dev/null +++ b/src/cor/params.h @@ -0,0 +1,51 @@ +/** + * params.h + * + * Creation Date: 25/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * A PARAM is a unified way to pass arguments to all macros that generate code. + * It is a tuple that contains the following parameters in order: + * + * PFX - Functions prefix + * SNAME - `struct` name + * SIZE - Size for SAC library + * K - Key type + * V - Value type + * + * PARAM := (PFX, SNAME, SIZE, K, V) + */ + +#ifndef CMC_COR_PARAMS_H +#define CMC_COR_PARAMS_H + +// clang-format off +/* +for i in range(5): + print(f"#define CMC_TUP_{i}_({', '.join(chr(x) for x in range(65, 65 + i + 1))}, ...) {chr(65 + i)}\n#define CMC_TUP_{i}(TUP) CMC_TUP_{i}_ TUP") +*/ +// clang-format on + +#define CMC_TUP_0_(A, ...) A +#define CMC_TUP_0(TUP) CMC_TUP_0_ TUP +#define CMC_TUP_1_(A, B, ...) B +#define CMC_TUP_1(TUP) CMC_TUP_1_ TUP +#define CMC_TUP_2_(A, B, C, ...) C +#define CMC_TUP_2(TUP) CMC_TUP_2_ TUP +#define CMC_TUP_3_(A, B, C, D, ...) D +#define CMC_TUP_3(TUP) CMC_TUP_3_ TUP +#define CMC_TUP_4_(A, B, C, D, E, ...) E +#define CMC_TUP_4(TUP) CMC_TUP_4_ TUP + +#define CMC_PARAM_PFX CMC_TUP_0 +#define CMC_PARAM_SNAME CMC_TUP_1 +#define CMC_PARAM_SIZE CMC_TUP_2 +#define CMC_PARAM_K CMC_TUP_3 +#define CMC_PARAM_V CMC_TUP_4 + +#endif /* CMC_COR_PARAMS_H */ From e9ee0a88b78c16a860fb1b67670ee99d0f63c640 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 25 May 2020 22:09:45 -0300 Subject: [PATCH 03/51] Added ext folder with some initial parts already using the new API --- Makefile | 5 ++- src/ext/cmc/deque.h | 86 +++++++++++++++++++++++++++++++++++++ src/ext/cmc/hashmap.h | 99 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 src/ext/cmc/deque.h create mode 100644 src/ext/cmc/hashmap.h diff --git a/Makefile b/Makefile index 64ac000..971ce61 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ .PHONY: all cmc dev sac utl tests FORCE -all: cmc cor dev sac utl tests +all: cmc cor dev ext sac utl tests cmc: FORCE clang-format --style=file -i ./src/cmc/*.h @@ -13,6 +13,9 @@ cor: FORCE dev: FORCE clang-format --style=file -i ./src/dev/*.h +ext: FORCE + clang-format --style=file -i ./src/ext/**/*.h + sac: FORCE clang-format --style=file -i ./src/sac/*.h diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h new file mode 100644 index 0000000..cf01c47 --- /dev/null +++ b/src/ext/cmc/deque.h @@ -0,0 +1,86 @@ +/** + * deque.h + * + * Creation Date: 25/05/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * Extensions to CMC + * + * - INIT + */ + +#ifndef CMC_EXT_CMC_DEQUE_H +#define CMC_EXT_CMC_DEQUE_H + +#include "../../cor/params.h" + +/** + * INIT + * + * The part 'INIT' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers) + */ +#define CMC_EXT_CMC_DEQUE_INIT(BODY) \ + CMC_EXT_CMC_DEQUE_INIT_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_INIT_SOURCE(BODY) + +#define CMC_EXT_CMC_DEQUE_INIT_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_INIT_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_INIT_SOURCE(BODY) \ + CMC_EXT_CMC_DEQUE_INIT_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ + \ + struct SNAME PFX##_init(size_t capacity, struct SNAME##_fval *f_val); \ + struct SNAME PFX##_init_custom( \ + size_t capacity, struct SNAME##_fval *f_val, \ + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); + +#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ + \ + struct SNAME PFX##_init(size_t capacity, struct SNAME##_fval *f_val) \ + { \ + return PFX##_init_custom(capacity, f_val, NULL, NULL); \ + } \ + \ + struct SNAME PFX##_init_custom( \ + size_t capacity, struct SNAME##_fval *f_val, \ + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + { \ + struct SNAME _deque_ = { 0 }; \ + \ + if (capacity < 1) \ + return _deque_; \ + \ + if (!f_val) \ + return _deque_; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ + \ + if (!_deque_.buffer) \ + return _deque_; \ + \ + _deque_.capacity = capacity; \ + _deque_.count = 0; \ + _deque_.front = 0; \ + _deque_.back = 0; \ + _deque_.flag = cmc_flags.OK; \ + _deque_.f_val = f_val; \ + _deque_.alloc = alloc; \ + _deque_.callbacks = callbacks; \ + \ + return _deque_; \ + } + +#endif /* CMC_EXT_CMC_DEQUE_H */ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h new file mode 100644 index 0000000..fde1147 --- /dev/null +++ b/src/ext/cmc/hashmap.h @@ -0,0 +1,99 @@ +/** + * hashmap.h + * + * Creation Date: 25/05/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * Extensions to CMC + * + * - INIT + */ + +#ifndef CMC_EXT_CMC_HASHMAP_H +#define CMC_EXT_CMC_HASHMAP_H + +#include "../../cor/params.h" + +/** + * INIT + * + * The part 'INIT' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#define CMC_EXT_CMC_HASHMAP_INIT(BODY) \ + 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_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_HEADER_(PFX, SNAME, V) \ + \ + struct SNAME PFX##_init(size_t capacity, double load, \ + struct SNAME##_fkey *f_key, \ + struct SNAME##_fval *f_val); \ + struct SNAME PFX##_init_custom( \ + size_t capacity, double load, struct SNAME##_fkey *f_key, \ + struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ + struct cmc_callbacks *callbacks); + +#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, V) \ + \ + struct SNAME PFX##_init(size_t capacity, double load, \ + struct SNAME##_fkey *f_key, \ + struct SNAME##_fval *f_val) \ + { \ + return PFX##_init_custom(capacity, load, f_key, f_val, NULL, NULL); \ + } \ + \ + struct SNAME PFX##_init_custom( \ + size_t capacity, double load, struct SNAME##_fkey *f_key, \ + struct SNAME##_fval *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 = 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_flags.OK; \ + _map_.f_key = f_key; \ + _map_.f_val = f_val; \ + _map_.alloc = alloc; \ + _map_.callbacks = callbacks; \ + \ + return _map_; \ + } + +#endif /* CMC_EXT_CMC_HASHMAP_H */ From 7fa0eafd2c141368c0b554eef8ff8e57539db9b9 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 26 May 2020 14:00:45 -0300 Subject: [PATCH 04/51] A lot of changes Changed include guards Removed struct cmc_flags, now using enum Token concatenation now uses CMC_ Every concatenation with SNAME now uses a special macro (this allows customization) Deleted some no longer needed test files Deleted some very old implementations of dev and sac collections --- src/cmc/bitset.h | 384 ++--- src/cmc/deque.h | 532 ++++--- src/cmc/hashbidimap.h | 918 ++++++------ src/cmc/hashmap.h | 2079 +++++++++++++------------- src/cmc/hashmultimap.h | 2582 +++++++++++++++++---------------- src/cmc/hashmultiset.h | 740 +++++----- src/cmc/hashset.h | 818 ++++++----- src/cmc/heap.h | 468 +++--- src/cmc/intervalheap.h | 527 +++---- src/cmc/linkedlist.h | 702 ++++----- src/cmc/list.h | 614 ++++---- src/cmc/queue.h | 461 +++--- src/cmc/sortedlist.h | 553 +++---- src/cmc/stack.h | 445 +++--- src/cmc/treemap.h | 517 +++---- src/cmc/treeset.h | 818 ++++++----- src/cor/alloc.h | 3 +- src/cor/core.h | 32 +- src/cor/flags.h | 28 +- src/dev/deque.h | 654 --------- src/ext/cmc/deque.h | 24 +- src/ext/cmc/hashbidimap.h | 0 src/ext/cmc/hashmap.h | 114 +- src/sac/queue.h | 357 ----- src/sac/stack.h | 327 ----- src/utl/assert.h | 6 +- src/utl/foreach.h | 22 +- src/utl/futils.h | 6 +- src/utl/log.h | 6 +- src/utl/mutex.h | 50 +- src/utl/test.h | 6 +- src/utl/thread.h | 32 +- src/utl/timer.h | 6 +- tests/contains.c | 260 ---- tests/foreach.c | 286 ---- tests/iterators.c | 139 -- tests/main/src/bitset.c | 36 +- tests/main/src/deque.c | 83 +- tests/main/src/hashbidimap.c | 102 +- tests/main/src/hashmap.c | 110 +- tests/main/src/hashmultimap.c | 96 +- tests/main/src/hashmultiset.c | 69 +- tests/main/src/hashset.c | 82 +- tests/main/src/heap.c | 42 +- tests/main/src/intervalheap.c | 65 +- tests/main/src/linkedlist.c | 84 +- tests/main/src/list.c | 102 +- tests/main/src/queue.c | 43 +- tests/main/src/sortedlist.c | 56 +- tests/main/src/stack.c | 42 +- tests/main/src/treemap.c | 65 +- tests/main/src/treeset.c | 47 +- tests/main/unt/bitset.c | 20 +- tests/main/unt/deque.c | 258 ++-- tests/main/unt/hashbidimap.c | 114 +- tests/main/unt/hashmap.c | 208 +-- tests/main/unt/hashmultimap.c | 98 +- tests/main/unt/hashmultiset.c | 88 +- tests/main/unt/hashset.c | 44 +- tests/main/unt/heap.c | 36 +- tests/main/unt/intervalheap.c | 90 +- tests/main/unt/linkedlist.c | 112 +- tests/main/unt/list.c | 122 +- tests/main/unt/queue.c | 44 +- tests/main/unt/sortedlist.c | 66 +- tests/main/unt/stack.c | 44 +- tests/main/unt/treemap.c | 68 +- tests/main/unt/treeset.c | 48 +- 68 files changed, 8188 insertions(+), 9912 deletions(-) delete mode 100644 src/dev/deque.h create mode 100644 src/ext/cmc/hashbidimap.h delete mode 100644 src/sac/queue.h delete mode 100644 src/sac/stack.h delete mode 100644 tests/contains.c delete mode 100644 tests/foreach.c delete mode 100644 tests/iterators.c diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index a4369ac..4045633 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -28,8 +28,8 @@ * as there is enough memory. */ -#ifndef CMC_BITSET_H -#define CMC_BITSET_H +#ifndef CMC_CMC_BITSET_H +#define CMC_CMC_BITSET_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -45,135 +45,143 @@ * BitSet specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_bitset = "struct %s " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "flag:%d, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_bitset = "struct %s " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "flag:%d, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_BITSET(PFX, SNAME) \ - CMC_GENERATE_BITSET_HEADER(PFX, SNAME) \ - CMC_GENERATE_BITSET_SOURCE(PFX, SNAME) +/** + * Core BitSet implementation + */ +#define CMC_CMC_BITSET_CORE(BODY) \ + CMC_CMC_BITSET_CORE_HEADER(BODY) \ + CMC_CMC_BITSET_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_BITSET_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_BITSET_HEADER(PFX, SNAME) +#define CMC_CMC_BITSET_CORE_HEADER(BODY) \ + CMC_CMC_BITSET_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY)) -#define CMC_WRAPGEN_BITSET_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_BITSET_SOURCE(PFX, SNAME) +#define CMC_CMC_BITSET_CORE_SOURCE(BODY) \ + CMC_CMC_BITSET_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_BITSET_HEADER(PFX, SNAME) \ - \ - /* BitSet Structure */ \ - struct SNAME \ - { \ - /* Dynamic Array of Bits */ \ - cmc_bitset_word *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* BitSet Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target bitset */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - cmc_bitset_word cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t n_bits); \ - struct SNAME *PFX##_new_custom(size_t n_bits, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - struct SNAME PFX##_init(size_t n_bits); \ - struct SNAME PFX##_init_custom(size_t n_bits, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - void PFX##_free(struct SNAME *_bitset_); \ - void PFX##_release(struct SNAME _bitset_); \ - void PFX##_customize(struct SNAME *_bitset_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_set(struct SNAME *_bitset_, size_t bit_index); \ - bool PFX##_set_range(struct SNAME *_bitset_, size_t from, size_t to); \ - bool PFX##_clear(struct SNAME *_bitset_, size_t bit_index); \ - bool PFX##_clear_range(struct SNAME *_bitset_, size_t from, size_t to); \ - bool PFX##_flip(struct SNAME *_bitset_, size_t bit_index); \ - bool PFX##_flip_range(struct SNAME *_bitset_, size_t from, size_t to); \ - bool PFX##_put(struct SNAME *_bitset_, size_t bit_index, bool state); \ - bool PFX##_put_range(struct SNAME *_bitset_, size_t from, size_t to, \ - bool state); \ - bool PFX##_set_all(struct SNAME *_bitset_); \ - bool PFX##_clear_all(struct SNAME *_bitset_); \ - bool PFX##_flip_all(struct SNAME *_bitset_); \ - /* Element Access */ \ - bool PFX##_get(struct SNAME *_bitset_, size_t bit_index); \ - /* Collection State */ \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_bitset_, size_t n_bits); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - /* Iterator State */ \ - /* Iterator Movement */ \ - /* Iterator Access */ \ - \ - /* Utility Methods */ \ - /* Translates a bit index to a word index */ \ - static inline size_t PFX##_bit_to_index(size_t idx) \ - { \ - /* Calculate how many shifts based on the size of cmc_bitset_word */ \ - static const size_t shift = \ - ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \ - ? 6 \ - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 \ - ? 5 \ - : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; \ - \ - return idx >> shift; \ +#define CMC_CMC_BITSET_CORE_HEADER_(PFX, SNAME) \ + \ + /* BitSet Structure */ \ + struct SNAME \ + { \ + /* Dynamic Array of Bits */ \ + cmc_bitset_word *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* BitSet Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target bitset */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + cmc_bitset_word cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t n_bits); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + struct SNAME CMC_(PFX, _init)(size_t n_bits); \ + struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _free)(struct SNAME * _bitset_); \ + void CMC_(PFX, _release)(struct SNAME _bitset_); \ + void CMC_(PFX, _customize)(struct SNAME * _bitset_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _set)(struct SNAME * _bitset_, size_t bit_index); \ + bool CMC_(PFX, _set_range)(struct SNAME * _bitset_, size_t from, \ + size_t to); \ + bool CMC_(PFX, _clear)(struct SNAME * _bitset_, size_t bit_index); \ + bool CMC_(PFX, _clear_range)(struct SNAME * _bitset_, size_t from, \ + size_t to); \ + bool CMC_(PFX, _flip)(struct SNAME * _bitset_, size_t bit_index); \ + bool CMC_(PFX, _flip_range)(struct SNAME * _bitset_, size_t from, \ + size_t to); \ + bool CMC_(PFX, _put)(struct SNAME * _bitset_, size_t bit_index, \ + bool state); \ + bool CMC_(PFX, _put_range)(struct SNAME * _bitset_, size_t from, \ + size_t to, bool state); \ + bool CMC_(PFX, _set_all)(struct SNAME * _bitset_); \ + bool CMC_(PFX, _clear_all)(struct SNAME * _bitset_); \ + bool CMC_(PFX, _flip_all)(struct SNAME * _bitset_); \ + /* Element Access */ \ + bool CMC_(PFX, _get)(struct SNAME * _bitset_, size_t bit_index); \ + /* Collection State */ \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _bitset_, size_t n_bits); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + /* Iterator State */ \ + /* Iterator Movement */ \ + /* Iterator Access */ \ + \ + /* Utility Methods */ \ + /* Translates a bit index to a word index */ \ + static inline size_t CMC_(PFX, _bit_to_index)(size_t idx) \ + { \ + /* Calculate how many shifts based on the size of cmc_bitset_word */ \ + static const size_t shift = \ + ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \ + ? 6 \ + : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 \ + ? 5 \ + : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; \ + \ + return idx >> shift; \ } /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_BITSET_SOURCE(PFX, SNAME) \ +#define CMC_CMC_BITSET_CORE_SOURCE_(PFX, SNAME) \ \ /* Implementation Detail Functions */ \ - bool PFX##_impl_resize(struct SNAME *_bitset_, size_t n_bits, \ - bool do_resize); \ + bool CMC_(PFX, _impl_resize)(struct SNAME * _bitset_, size_t n_bits, \ + bool do_resize); \ \ - struct SNAME *PFX##_new(size_t n_bits) \ + struct SNAME *CMC_(PFX, _new)(size_t n_bits) \ { \ - return PFX##_new_custom(n_bits, NULL, NULL); \ + return CMC_(PFX, _new_custom)(n_bits, NULL, NULL); \ } \ \ - struct SNAME *PFX##_new_custom(size_t n_bits, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (n_bits < 1) \ return NULL; \ @@ -181,7 +189,7 @@ static const char *cmc_string_fmt_bitset = "struct %s " if (!alloc) \ alloc = &cmc_alloc_node_default; \ \ - size_t capacity = PFX##_bit_to_index(n_bits - 1) + 1; \ + size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ \ struct SNAME *_bitset_ = alloc->malloc(sizeof(struct SNAME)); \ \ @@ -197,21 +205,21 @@ static const char *cmc_string_fmt_bitset = "struct %s " } \ \ _bitset_->capacity = capacity; \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ _bitset_->alloc = alloc; \ _bitset_->callbacks = callbacks; \ \ return _bitset_; \ } \ \ - struct SNAME PFX##_init(size_t n_bits) \ + struct SNAME CMC_(PFX, _init)(size_t n_bits) \ { \ - return PFX##_init_custom(n_bits, NULL, NULL); \ + return CMC_(PFX, _init_custom)(n_bits, NULL, NULL); \ } \ \ - struct SNAME PFX##_init_custom(size_t n_bits, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ struct SNAME _bitset_ = { 0 }; \ \ @@ -221,7 +229,7 @@ static const char *cmc_string_fmt_bitset = "struct %s " if (!alloc) \ alloc = &cmc_alloc_node_default; \ \ - size_t capacity = PFX##_bit_to_index(n_bits - 1) + 1; \ + size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ \ _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ \ @@ -229,26 +237,27 @@ static const char *cmc_string_fmt_bitset = "struct %s " return _bitset_; \ \ _bitset_.capacity = capacity; \ - _bitset_.flag = cmc_flags.OK; \ + _bitset_.flag = CMC_FLAG_OK; \ _bitset_.alloc = alloc; \ _bitset_.callbacks = callbacks; \ \ return _bitset_; \ } \ \ - void PFX##_free(struct SNAME *_bitset_) \ + void CMC_(PFX, _free)(struct SNAME * _bitset_) \ { \ free(_bitset_->buffer); \ free(_bitset_); \ } \ \ - void PFX##_release(struct SNAME _bitset_) \ + void CMC_(PFX, _release)(struct SNAME _bitset_) \ { \ free(_bitset_.buffer); \ } \ \ - void PFX##_customize(struct SNAME *_bitset_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _bitset_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _bitset_->alloc = &cmc_alloc_node_default; \ @@ -257,22 +266,22 @@ static const char *cmc_string_fmt_bitset = "struct %s " \ _bitset_->callbacks = callbacks; \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_set(struct SNAME *_bitset_, size_t bit_index) \ + bool CMC_(PFX, _set)(struct SNAME * _bitset_, size_t bit_index) \ { \ - if (!PFX##_impl_resize(_bitset_, bit_index + 1, false)) \ + if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ return false; \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = PFX##_bit_to_index(bit_index); \ + size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ \ _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->create) \ _bitset_->callbacks->create(); \ @@ -280,19 +289,20 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_set_range(struct SNAME *_bitset_, size_t from, size_t to) \ + bool CMC_(PFX, _set_range)(struct SNAME * _bitset_, size_t from, \ + size_t to) \ { \ if (to < from) \ { \ - _bitset_->flag = cmc_flags.INVALID; \ + _bitset_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ - if (!PFX##_impl_resize(_bitset_, to + 1, false)) \ + if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = PFX##_bit_to_index(from); \ - size_t end_index = PFX##_bit_to_index(to); \ + size_t start_index = CMC_(PFX, _bit_to_index)(from); \ + size_t end_index = CMC_(PFX, _bit_to_index)(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -320,7 +330,7 @@ static const char *cmc_string_fmt_bitset = "struct %s " _bitset_->buffer[end_index] |= end_mask; \ } \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->create) \ _bitset_->callbacks->create(); \ @@ -328,19 +338,19 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_clear(struct SNAME *_bitset_, size_t bit_index) \ + bool CMC_(PFX, _clear)(struct SNAME * _bitset_, size_t bit_index) \ { \ - if (!PFX##_impl_resize(_bitset_, bit_index + 1, false)) \ + if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ return false; \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = PFX##_bit_to_index(bit_index); \ + size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ \ _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->delete) \ _bitset_->callbacks->delete (); \ @@ -348,19 +358,20 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_clear_range(struct SNAME *_bitset_, size_t from, size_t to) \ + bool CMC_(PFX, _clear_range)(struct SNAME * _bitset_, size_t from, \ + size_t to) \ { \ if (to < from) \ { \ - _bitset_->flag = cmc_flags.INVALID; \ + _bitset_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ - if (!PFX##_impl_resize(_bitset_, to + 1, false)) \ + if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = PFX##_bit_to_index(from); \ - size_t end_index = PFX##_bit_to_index(to); \ + size_t start_index = CMC_(PFX, _bit_to_index)(from); \ + size_t end_index = CMC_(PFX, _bit_to_index)(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -388,7 +399,7 @@ static const char *cmc_string_fmt_bitset = "struct %s " _bitset_->buffer[end_index] &= ~end_mask; \ } \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->delete) \ _bitset_->callbacks->delete (); \ @@ -396,19 +407,19 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_flip(struct SNAME *_bitset_, size_t bit_index) \ + bool CMC_(PFX, _flip)(struct SNAME * _bitset_, size_t bit_index) \ { \ - if (!PFX##_impl_resize(_bitset_, bit_index + 1, false)) \ + if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ return false; \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = PFX##_bit_to_index(bit_index); \ + size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ \ _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->update) \ _bitset_->callbacks->update(); \ @@ -416,19 +427,20 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_flip_range(struct SNAME *_bitset_, size_t from, size_t to) \ + bool CMC_(PFX, _flip_range)(struct SNAME * _bitset_, size_t from, \ + size_t to) \ { \ if (to < from) \ { \ - _bitset_->flag = cmc_flags.INVALID; \ + _bitset_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ - if (!PFX##_impl_resize(_bitset_, to + 1, false)) \ + if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = PFX##_bit_to_index(from); \ - size_t end_index = PFX##_bit_to_index(to); \ + size_t start_index = CMC_(PFX, _bit_to_index)(from); \ + size_t end_index = CMC_(PFX, _bit_to_index)(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -456,7 +468,7 @@ static const char *cmc_string_fmt_bitset = "struct %s " _bitset_->buffer[end_index] ^= end_mask; \ } \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->update) \ _bitset_->callbacks->update(); \ @@ -464,29 +476,30 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_put(struct SNAME *_bitset_, size_t bit_index, bool state) \ - { \ - if (state) \ - return PFX##_set(_bitset_, bit_index); \ - else \ - return PFX##_clear(_bitset_, bit_index); \ - } \ - \ - bool PFX##_put_range(struct SNAME *_bitset_, size_t from, size_t to, \ + bool CMC_(PFX, _put)(struct SNAME * _bitset_, size_t bit_index, \ bool state) \ { \ if (state) \ - return PFX##_set_range(_bitset_, from, to); \ + return CMC_(PFX, _set)(_bitset_, bit_index); \ else \ - return PFX##_clear_range(_bitset_, from, to); \ + return CMC_(PFX, _clear)(_bitset_, bit_index); \ } \ \ - bool PFX##_set_all(struct SNAME *_bitset_) \ + bool CMC_(PFX, _put_range)(struct SNAME * _bitset_, size_t from, \ + size_t to, bool state) \ + { \ + if (state) \ + return CMC_(PFX, _set_range)(_bitset_, from, to); \ + else \ + return CMC_(PFX, _clear_range)(_bitset_, from, to); \ + } \ + \ + bool CMC_(PFX, _set_all)(struct SNAME * _bitset_) \ { \ for (size_t i = 0; i < _bitset_->capacity; i++) \ _bitset_->buffer[i] = ~((cmc_bitset_word)0); \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->create) \ _bitset_->callbacks->create(); \ @@ -494,12 +507,12 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_clear_all(struct SNAME *_bitset_) \ + bool CMC_(PFX, _clear_all)(struct SNAME * _bitset_) \ { \ for (size_t i = 0; i < _bitset_->capacity; i++) \ _bitset_->buffer[i] = 0; \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->delete) \ _bitset_->callbacks->delete (); \ @@ -507,12 +520,12 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_flip_all(struct SNAME *_bitset_) \ + bool CMC_(PFX, _flip_all)(struct SNAME * _bitset_) \ { \ for (size_t i = 0; i < _bitset_->capacity; i++) \ _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->create) \ _bitset_->callbacks->create(); \ @@ -520,35 +533,36 @@ static const char *cmc_string_fmt_bitset = "struct %s " return true; \ } \ \ - bool PFX##_get(struct SNAME *_bitset_, size_t bit_index) \ + bool CMC_(PFX, _get)(struct SNAME * _bitset_, size_t bit_index) \ { \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - cmc_bitset_word w = _bitset_->buffer[PFX##_bit_to_index(bit_index)]; \ + cmc_bitset_word w = \ + _bitset_->buffer[CMC_(PFX, _bit_to_index)(bit_index)]; \ \ return w & ((cmc_bitset_word)1 << (bit_index % bits)); \ } \ \ - bool PFX##_resize(struct SNAME *_bitset_, size_t n_bits) \ + bool CMC_(PFX, _resize)(struct SNAME * _bitset_, size_t n_bits) \ { \ - return PFX##_impl_resize(_bitset_, n_bits, true); \ + return CMC_(PFX, _impl_resize)(_bitset_, n_bits, true); \ } \ \ /* When do_resize is false, then we just want to assure that the bitset */ \ /* can accommodate n_bits */ \ - bool PFX##_impl_resize(struct SNAME *_bitset_, size_t n_bits, \ - bool do_resize) \ + bool CMC_(PFX, _impl_resize)(struct SNAME * _bitset_, size_t n_bits, \ + bool do_resize) \ { \ if (n_bits == 0) \ { \ - _bitset_->flag = cmc_flags.INVALID; \ + _bitset_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ /* -1 because n_bits is 1-based and we need to pass a 0-based index */ \ /* +1 to have a 1-based result */ \ - size_t words = PFX##_bit_to_index(n_bits - 1) + 1; \ + size_t words = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ \ /* Be sure we are not always shrinking when we just want to make */ \ /* sure that we have enough size for n_bits */ \ @@ -560,7 +574,7 @@ static const char *cmc_string_fmt_bitset = "struct %s " \ if (!new_buffer) \ { \ - _bitset_->flag = cmc_flags.ALLOC; \ + _bitset_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -576,9 +590,9 @@ static const char *cmc_string_fmt_bitset = "struct %s " if (_bitset_->callbacks && _bitset_->callbacks->resize) \ _bitset_->callbacks->resize(); \ \ - _bitset_->flag = cmc_flags.OK; \ + _bitset_->flag = CMC_FLAG_OK; \ \ return true; \ } -#endif /* CMC_BITSET_H */ +#endif /* CMC_CMC_BITSET_H */ diff --git a/src/cmc/deque.h b/src/cmc/deque.h index bea757e..5b6dffa 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -28,8 +28,8 @@ * would take O(N) due to the need to shift all elements in the deque. */ -#ifndef CMC_DEQUE_H -#define CMC_DEQUE_H +#ifndef CMC_CMC_DEQUE_H +#define CMC_CMC_DEQUE_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -40,177 +40,184 @@ * Deque Specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *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 }"; +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 }"; -#define CMC_GENERATE_DEQUE(PFX, SNAME, V) \ - CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V) +/** + * Core Deque implementation + */ +#define CMC_CMC_DEQUE_CORE(BODY) \ + CMC_CMC_DEQUE_CORE_HEADER(BODY) \ + CMC_CMC_DEQUE_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_DEQUE_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) +#define CMC_CMC_DEQUE_CORE_HEADER(BODY) \ + CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_DEQUE_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V) +#define CMC_CMC_DEQUE_CORE_SOURCE(BODY) \ + CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) \ - \ - /* Deque Structure */ \ - struct SNAME \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ - \ - /* Current circular array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Index representing the front of the deque */ \ - size_t front; \ - \ - /* Index representing the back of the deque */ \ - size_t back; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Deque Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target deque */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - struct SNAME PFX##_init(size_t capacity, struct SNAME##_fval *f_val); \ - struct SNAME PFX##_init_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_deque_); \ - void PFX##_free(struct SNAME *_deque_); \ - void PFX##_release(struct SNAME _deque_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_deque_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_push_front(struct SNAME *_deque_, V value); \ - bool PFX##_push_back(struct SNAME *_deque_, V value); \ - bool PFX##_pop_front(struct SNAME *_deque_); \ - bool PFX##_pop_back(struct SNAME *_deque_); \ - /* Element Access */ \ - V PFX##_front(struct SNAME *_deque_); \ - V PFX##_back(struct SNAME *_deque_); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_deque_, V value); \ - bool PFX##_empty(struct SNAME *_deque_); \ - bool PFX##_full(struct SNAME *_deque_); \ - size_t PFX##_count(struct SNAME *_deque_); \ - size_t PFX##_capacity(struct SNAME *_deque_); \ - int PFX##_flag(struct SNAME *_deque_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_deque_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_deque_); \ - bool PFX##_equals(struct SNAME *_deque1_, struct SNAME *_deque2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_deque_); \ - bool PFX##_print(struct SNAME *_deque_, FILE *fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Deque Structure */ \ + struct SNAME \ + { \ + /* Dynamic circular array of elements */ \ + V *buffer; \ + \ + /* Current circular array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Index representing the front of the deque */ \ + size_t front; \ + \ + /* Index representing the back of the deque */ \ + size_t back; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Deque Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target deque */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _deque_); \ + void CMC_(PFX, _free)(struct SNAME * _deque_); \ + void CMC_(PFX, _release)(struct SNAME _deque_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _deque_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _deque_); \ + V CMC_(PFX, _back)(struct SNAME * _deque_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _deque_); \ + bool CMC_(PFX, _full)(struct SNAME * _deque_); \ + size_t CMC_(PFX, _count)(struct SNAME * _deque_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \ + int CMC_(PFX, _flag)(struct SNAME * _deque_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \ + bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _deque_); \ + bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ /* None */ \ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ - return PFX##_new_custom(capacity, f_val, NULL, NULL); \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ if (capacity < 1) \ return NULL; \ @@ -238,7 +245,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " _deque_->count = 0; \ _deque_->front = 0; \ _deque_->back = 0; \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ _deque_->f_val = f_val; \ _deque_->alloc = alloc; \ _deque_->callbacks = callbacks; \ @@ -246,44 +253,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return _deque_; \ } \ \ - struct SNAME PFX##_init(size_t capacity, struct SNAME##_fval *f_val) \ - { \ - return PFX##_init_custom(capacity, f_val, NULL, NULL); \ - } \ - \ - struct SNAME PFX##_init_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ - { \ - struct SNAME _deque_ = { 0 }; \ - \ - if (capacity < 1) \ - return _deque_; \ - \ - if (!f_val) \ - return _deque_; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_deque_.buffer) \ - return _deque_; \ - \ - _deque_.capacity = capacity; \ - _deque_.count = 0; \ - _deque_.front = 0; \ - _deque_.back = 0; \ - _deque_.flag = cmc_flags.OK; \ - _deque_.f_val = f_val; \ - _deque_.alloc = alloc; \ - _deque_.callbacks = callbacks; \ - \ - return _deque_; \ - } \ - \ - void PFX##_clear(struct SNAME *_deque_) \ + void CMC_(PFX, _clear)(struct SNAME * _deque_) \ { \ if (_deque_->f_val->free) \ { \ @@ -301,10 +271,10 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " _deque_->front = 0; \ _deque_->back = 0; \ \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_deque_) \ + void CMC_(PFX, _free)(struct SNAME * _deque_) \ { \ if (_deque_->f_val->free) \ { \ @@ -320,7 +290,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " _deque_->alloc->free(_deque_); \ } \ \ - void PFX##_release(struct SNAME _deque_) \ + void CMC_(PFX, _release)(struct SNAME _deque_) \ { \ if (_deque_.f_val->free) \ { \ @@ -335,8 +305,9 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " _deque_.alloc->free(_deque_.buffer); \ } \ \ - void PFX##_customize(struct SNAME *_deque_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _deque_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _deque_->alloc = &cmc_alloc_node_default; \ @@ -345,14 +316,14 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " \ _deque_->callbacks = callbacks; \ \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_push_front(struct SNAME *_deque_, V value) \ + bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \ { \ - if (PFX##_full(_deque_)) \ + if (CMC_(PFX, _full)(_deque_)) \ { \ - if (!PFX##_resize(_deque_, _deque_->capacity * 2)) \ + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ return false; \ } \ \ @@ -362,7 +333,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " _deque_->buffer[_deque_->front] = value; \ \ _deque_->count++; \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ if (_deque_->callbacks && _deque_->callbacks->create) \ _deque_->callbacks->create(); \ @@ -370,11 +341,11 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return true; \ } \ \ - bool PFX##_push_back(struct SNAME *_deque_, V value) \ + bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \ { \ - if (PFX##_full(_deque_)) \ + if (CMC_(PFX, _full)(_deque_)) \ { \ - if (!PFX##_resize(_deque_, _deque_->capacity * 2)) \ + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ return false; \ } \ \ @@ -384,7 +355,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ \ _deque_->count++; \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ if (_deque_->callbacks && _deque_->callbacks->create) \ _deque_->callbacks->create(); \ @@ -392,11 +363,11 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop_front(struct SNAME *_deque_) \ + bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \ { \ - if (PFX##_empty(_deque_)) \ + if (CMC_(PFX, _empty)(_deque_)) \ { \ - _deque_->flag = cmc_flags.EMPTY; \ + _deque_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -407,7 +378,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " : _deque_->front + 1; \ \ _deque_->count--; \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ if (_deque_->callbacks && _deque_->callbacks->delete) \ _deque_->callbacks->delete (); \ @@ -415,11 +386,11 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop_back(struct SNAME *_deque_) \ + bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \ { \ - if (PFX##_empty(_deque_)) \ + if (CMC_(PFX, _empty)(_deque_)) \ { \ - _deque_->flag = cmc_flags.EMPTY; \ + _deque_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -429,7 +400,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " _deque_->buffer[_deque_->back] = (V){ 0 }; \ \ _deque_->count--; \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ if (_deque_->callbacks && _deque_->callbacks->delete) \ _deque_->callbacks->delete (); \ @@ -437,15 +408,15 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return true; \ } \ \ - V PFX##_front(struct SNAME *_deque_) \ + V CMC_(PFX, _front)(struct SNAME * _deque_) \ { \ - if (PFX##_empty(_deque_)) \ + if (CMC_(PFX, _empty)(_deque_)) \ { \ - _deque_->flag = cmc_flags.EMPTY; \ + _deque_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ if (_deque_->callbacks && _deque_->callbacks->read) \ _deque_->callbacks->read(); \ @@ -453,15 +424,15 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return _deque_->buffer[_deque_->front]; \ } \ \ - V PFX##_back(struct SNAME *_deque_) \ + V CMC_(PFX, _back)(struct SNAME * _deque_) \ { \ - if (PFX##_empty(_deque_)) \ + if (CMC_(PFX, _empty)(_deque_)) \ { \ - _deque_->flag = cmc_flags.EMPTY; \ + _deque_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ if (_deque_->callbacks && _deque_->callbacks->read) \ _deque_->callbacks->read(); \ @@ -470,9 +441,9 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " : _deque_->back - 1]; \ } \ \ - bool PFX##_contains(struct SNAME *_deque_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \ { \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ bool result = false; \ \ @@ -493,41 +464,41 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_deque_) \ + bool CMC_(PFX, _empty)(struct SNAME * _deque_) \ { \ return _deque_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_deque_) \ + bool CMC_(PFX, _full)(struct SNAME * _deque_) \ { \ return _deque_->count >= _deque_->capacity; \ } \ \ - size_t PFX##_count(struct SNAME *_deque_) \ + size_t CMC_(PFX, _count)(struct SNAME * _deque_) \ { \ return _deque_->count; \ } \ \ - size_t PFX##_capacity(struct SNAME *_deque_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \ { \ return _deque_->capacity; \ } \ \ - int PFX##_flag(struct SNAME *_deque_) \ + int CMC_(PFX, _flag)(struct SNAME * _deque_) \ { \ return _deque_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_deque_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \ { \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ if (_deque_->capacity == capacity) \ goto success; \ \ if (capacity < _deque_->count) \ { \ - _deque_->flag = cmc_flags.INVALID; \ + _deque_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ @@ -535,7 +506,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " \ if (!new_buffer) \ { \ - _deque_->flag = cmc_flags.ALLOC; \ + _deque_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -561,15 +532,15 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_deque_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \ { \ struct SNAME *result = \ - PFX##_new_custom(_deque_->capacity, _deque_->f_val, \ - _deque_->alloc, _deque_->callbacks); \ + CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, \ + _deque_->alloc, _deque_->callbacks); \ \ if (!result) \ { \ - _deque_->flag = cmc_flags.ERROR; \ + _deque_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ @@ -596,15 +567,15 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " result->front = 0; \ result->back = _deque_->count; \ \ - _deque_->flag = cmc_flags.OK; \ + _deque_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_deque1_, struct SNAME *_deque2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \ { \ - _deque1_->flag = cmc_flags.OK; \ - _deque2_->flag = cmc_flags.OK; \ + _deque1_->flag = CMC_FLAG_OK; \ + _deque2_->flag = CMC_FLAG_OK; \ \ if (_deque1_->count != _deque2_->count) \ return false; \ @@ -624,20 +595,20 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_deque_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _deque_) \ { \ struct cmc_string str; \ struct SNAME *d_ = _deque_; \ \ int n = \ - snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, #SNAME, #V, \ - d_, d_->buffer, d_->capacity, d_->count, d_->front, \ + snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_deque, #SNAME, \ + #V, d_, d_->buffer, d_->capacity, d_->count, d_->front, \ d_->back, d_->flag, d_->f_val, d_->alloc, d_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_deque_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr) \ { \ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ { \ @@ -650,26 +621,26 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = target->front; \ iter.index = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ if (iter.target->back == 0) \ iter.cursor = iter.target->capacity - 1; \ @@ -684,25 +655,25 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " iter.index = 0; \ } \ \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->target->front; \ iter->index = 0; \ @@ -715,9 +686,9 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ if (iter->target->back == 0) \ iter->cursor = iter->target->capacity - 1; \ @@ -735,7 +706,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -746,7 +717,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ iter->index++; \ @@ -754,7 +725,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -765,7 +736,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \ : iter->cursor - 1; \ @@ -775,7 +746,8 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -789,7 +761,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " if (steps == 0 || iter->index + steps >= iter->target->count) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->index += steps; \ iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ @@ -798,7 +770,8 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -812,7 +785,7 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " if (steps == 0 || iter->index < steps) \ return false; \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->index -= steps; \ \ @@ -827,38 +800,39 @@ static const char *cmc_string_fmt_deque = "struct %s<%s> " \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor]; \ } \ \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return NULL; \ \ return &(iter->target->buffer[iter->cursor]); \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->index; \ } -#endif /* CMC_DEQUE_H */ +#endif /* CMC_CMC_DEQUE_H */ diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index a0885e8..00006d6 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -23,8 +23,8 @@ * the key and the value. */ -#ifndef CMC_HASHBIDIMAP_H -#define CMC_HASHBIDIMAP_H +#ifndef CMC_CMC_HASHBIDIMAP_H +#define CMC_CMC_HASHBIDIMAP_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -40,248 +40,264 @@ * HashBidimap Specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_hashbidimap = "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 }"; +static const char *cmc_cmc_string_fmt_hashbidimap = "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 }"; -#define CMC_GENERATE_HASHBIDIMAP(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) +/** + * Core HashBidiMap implementation + */ +#define CMC_CMC_HASHBIDIMAP_CORE(BODY) \ + CMC_CMC_HASHBIDIMAP_CORE_HEADER(BODY) \ + CMC_CMC_HASHBIDIMAP_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) +#define CMC_CMC_HASHBIDIMAP_CORE_HEADER(BODY) \ + CMC_CMC_HASHBIDIMAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) +#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE(BODY) \ + CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \ - \ - /* HashBidiMap Structure */ \ - struct SNAME \ - { \ - /* Array 0 is K -> V and array 1 is V -> K */ \ - struct SNAME##_entry *(*buffer)[2]; \ - \ - /* Current arrays capacity */ \ - size_t capacity; \ - \ - /* Current amount of keys */ \ - size_t count; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Key function table */ \ - struct SNAME##_fkey *f_key; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - \ - /* Methods */ \ - /* Returns an iterator to the start of the hashbidimap */ \ - struct SNAME##_iter (*it_start)(struct SNAME *); \ - \ - /* Returns an iterator to the end of the hashbidimap */ \ - struct SNAME##_iter (*it_end)(struct SNAME *); \ - }; \ - \ - /* HashBidiMap Entry */ \ - struct SNAME##_entry \ - { \ - /* Entry Key */ \ - K key; \ - \ - /* Entry Value */ \ - V value; \ - \ - /* The distance of this node to its original position */ \ - /* dist[0] is relative to K -> V */ \ - /* dist[1] is relative to V -> K */ \ - size_t dist[2]; \ - \ - /* References to this node in the hashbidimap buffer. Used to */ \ - /* prevent searching for this node twice for update() and */ \ - /* remove(). Increases memory overhead but reduces execution time */ \ - /* ref[0] is relative to K -> V */ \ - /* ref[1] is relative to V -> K */ \ - struct SNAME##_entry **ref[2]; \ - }; \ - \ - /* Key struct function table */ \ - struct SNAME##_fkey \ - { \ - /* Comparator function */ \ - int (*cmp)(K, K); \ - \ - /* Copy function */ \ - K (*cpy)(K); \ - \ - /* To string function */ \ - bool (*str)(FILE *, K); \ - \ - /* Free from memory function */ \ - void (*free)(K); \ - \ - /* Hash function */ \ - size_t (*hash)(K); \ - \ - /* Priority function */ \ - int (*pri)(K, K); \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* HashBidiMap Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target hashbidimap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_map_); \ - void PFX##_free(struct SNAME *_map_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_map_, K key, V value); \ - bool PFX##_update_key(struct SNAME *_map_, V val, K new_key); \ - bool PFX##_update_val(struct SNAME *_map_, K key, V new_val); \ - bool PFX##_remove_by_key(struct SNAME *_map_, K key, K *out_key, \ - V *out_val); \ - bool PFX##_remove_by_val(struct SNAME *_map_, V val, K *out_key, \ - V *out_val); \ - /* Element Access */ \ - K PFX##_get_key(struct SNAME *_map_, V val); \ - V PFX##_get_val(struct SNAME *_map_, K key); \ - /* Collection State */ \ - bool PFX##_contains_key(struct SNAME *_map_, K key); \ - bool PFX##_contains_val(struct SNAME *_map_, V val); \ - bool PFX##_empty(struct SNAME *_map_); \ - bool PFX##_full(struct SNAME *_map_); \ - size_t PFX##_count(struct SNAME *_map_); \ - size_t PFX##_capacity(struct SNAME *_map_); \ - double PFX##_load(struct SNAME *_map_); \ - int PFX##_flag(struct SNAME *_map_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_map_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_); \ - bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_map_); \ - bool PFX##_print(struct SNAME *_map_, FILE *fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Allocation and Deallocation */ \ - struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \ - void PFX##_iter_free(struct SNAME##_iter *iter); \ - /* Iterator Initialization */ \ - void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - void PFX##_iter_to_start(struct SNAME##_iter *iter); \ - void PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - K PFX##_iter_key(struct SNAME##_iter *iter); \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_HASHBIDIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ + \ + /* HashBidiMap Structure */ \ + struct SNAME \ + { \ + /* Array 0 is K -> V and array 1 is V -> K */ \ + struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ + \ + /* Current arrays capacity */ \ + size_t capacity; \ + \ + /* Current amount of keys */ \ + size_t count; \ + \ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Key function table */ \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + \ + /* Methods */ \ + /* Returns an iterator to the start of the hashbidimap */ \ + struct CMC_DEF_ITER(SNAME) (*it_start)(struct SNAME *); \ + \ + /* Returns an iterator to the end of the hashbidimap */ \ + struct CMC_DEF_ITER(SNAME) (*it_end)(struct SNAME *); \ + }; \ + \ + /* HashBidiMap Entry */ \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry Key */ \ + K key; \ + \ + /* Entry Value */ \ + V value; \ + \ + /* The distance of this node to its original position */ \ + /* dist[0] is relative to K -> V */ \ + /* dist[1] is relative to V -> K */ \ + size_t dist[2]; \ + \ + /* References to this node in the hashbidimap buffer. Used to */ \ + /* prevent searching for this node twice for update() and */ \ + /* remove(). Increases memory overhead but reduces execution time */ \ + /* ref[0] is relative to K -> V */ \ + /* ref[1] is relative to V -> K */ \ + struct CMC_DEF_ENTRY(SNAME) * *ref[2]; \ + }; \ + \ + /* Key struct function table */ \ + struct CMC_DEF_FKEY(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(K, K); \ + \ + /* Copy function */ \ + K (*cpy)(K); \ + \ + /* To string function */ \ + bool (*str)(FILE *, K); \ + \ + /* Free from memory function */ \ + void (*free)(K); \ + \ + /* Hash function */ \ + size_t (*hash)(K); \ + \ + /* Priority function */ \ + int (*pri)(K, K); \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* HashBidiMap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target hashbidimap */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* The index of the first element */ \ + size_t first; \ + \ + /* The index of the last element */ \ + size_t last; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_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); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key); \ + bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val); \ + bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, \ + V * out_val); \ + bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, \ + V * out_val); \ + /* Element Access */ \ + K CMC_(PFX, _get_key)(struct SNAME * _map_, V val); \ + V CMC_(PFX, _get_val)(struct SNAME * _map_, K key); \ + /* Collection State */ \ + bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + bool CMC_(PFX, _full)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ + double CMC_(PFX, _load)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ + \ + /* Iterator Functions */ \ + /* Iterator Allocation and Deallocation */ \ + struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target); \ + void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Initialization */ \ + void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, \ + struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) \ +#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ \ /* Implementation Detail Functions */ \ - static struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, \ - K key, V value); \ - static struct SNAME##_entry **PFX##_impl_get_entry_by_key( \ - struct SNAME *_map_, K key); \ - static struct SNAME##_entry **PFX##_impl_get_entry_by_val( \ - struct SNAME *_map_, V val); \ - static struct SNAME##_entry **PFX##_impl_add_entry_to_key( \ - struct SNAME *_map_, struct SNAME##_entry *entry); \ - static struct SNAME##_entry **PFX##_impl_add_entry_to_val( \ - struct SNAME *_map_, struct SNAME##_entry *entry); \ - static size_t PFX##_impl_calculate_size(size_t required); \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_map_); \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_add_entry_to_key)( \ + struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_add_entry_to_val)( \ + struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ + static struct CMC_DEF_ITER(SNAME) \ + CMC_(PFX, _impl_it_start)(struct SNAME * _map_); \ + static struct CMC_DEF_ITER(SNAME) \ + CMC_(PFX, _impl_it_end)(struct SNAME * _map_); \ \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -295,15 +311,16 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (!f_key || !f_val) \ return NULL; \ \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ \ struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ \ if (!_map_) \ return NULL; \ \ - _map_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry *[2])); \ + _map_->buffer = alloc->calloc( \ + real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ \ if (!_map_->buffer) \ { \ @@ -315,21 +332,21 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " _map_->count = 0; \ _map_->capacity = real_capacity; \ _map_->load = load; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ _map_->f_key = f_key; \ _map_->f_val = f_val; \ _map_->alloc = alloc; \ _map_->callbacks = NULL; \ - _map_->it_start = PFX##_impl_it_start; \ - _map_->it_end = PFX##_impl_it_end; \ + _map_->it_start = CMC_(PFX, _impl_it_start); \ + _map_->it_end = CMC_(PFX, _impl_it_end); \ \ return _map_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_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) \ { \ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ @@ -341,7 +358,8 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (!f_key || !f_val) \ return NULL; \ \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ \ if (!alloc) \ alloc = &cmc_alloc_node_default; \ @@ -351,8 +369,8 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (!_map_) \ return NULL; \ \ - _map_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry *[2])); \ + _map_->buffer = alloc->calloc( \ + real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ \ if (!_map_->buffer) \ { \ @@ -364,23 +382,23 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " _map_->count = 0; \ _map_->capacity = real_capacity; \ _map_->load = load; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ _map_->f_key = f_key; \ _map_->f_val = f_val; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ _map_->alloc = alloc; \ _map_->callbacks = callbacks; \ - _map_->it_start = PFX##_impl_it_start; \ - _map_->it_end = PFX##_impl_it_end; \ + _map_->it_start = CMC_(PFX, _impl_it_start); \ + _map_->it_end = CMC_(PFX, _impl_it_end); \ \ return _map_; \ } \ \ - void PFX##_clear(struct SNAME *_map_) \ + void CMC_(PFX, _clear)(struct SNAME * _map_) \ { \ for (size_t i = 0; i < _map_->capacity; i++) \ { \ - struct SNAME##_entry *entry = _map_->buffer[i][0]; \ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i][0]; \ \ if (entry && entry != CMC_ENTRY_DELETED) \ { \ @@ -397,19 +415,20 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " } \ \ _map_->count = 0; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_map_) \ + void CMC_(PFX, _free)(struct SNAME * _map_) \ { \ - PFX##_clear(_map_); \ + CMC_(PFX, _clear)(_map_); \ \ _map_->alloc->free(_map_->buffer); \ _map_->alloc->free(_map_); \ } \ \ - void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ @@ -418,30 +437,31 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ _map_->callbacks = callbacks; \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_insert(struct SNAME *_map_, K key, V value) \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ { \ - if (PFX##_full(_map_)) \ + if (CMC_(PFX, _full)(_map_)) \ { \ - if (!PFX##_resize(_map_, _map_->capacity + 1)) \ + if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ return false; \ } \ \ - if (PFX##_impl_get_entry_by_key(_map_, key) != NULL || \ - PFX##_impl_get_entry_by_val(_map_, value) != NULL) \ + if (CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL || \ + CMC_(PFX, _impl_get_entry_by_val)(_map_, value) != NULL) \ { \ - _map_->flag = cmc_flags.DUPLICATE; \ + _map_->flag = CMC_FLAG_DUPLICATE; \ return false; \ } \ \ - struct SNAME##_entry *entry = PFX##_impl_new_entry(_map_, key, value); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_new_entry)(_map_, key, value); \ \ - struct SNAME##_entry **key_entry = \ - PFX##_impl_add_entry_to_key(_map_, entry); \ - struct SNAME##_entry **val_entry = \ - PFX##_impl_add_entry_to_val(_map_, entry); \ + struct CMC_DEF_ENTRY(SNAME) **key_entry = \ + CMC_(PFX, _impl_add_entry_to_key)(_map_, entry); \ + struct CMC_DEF_ENTRY(SNAME) **val_entry = \ + CMC_(PFX, _impl_add_entry_to_val)(_map_, entry); \ \ if (!key_entry || !val_entry) \ { \ @@ -452,13 +472,13 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ _map_->alloc->free(entry); \ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ \ return false; \ } \ \ _map_->count++; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->create) \ _map_->callbacks->create(); \ @@ -466,21 +486,21 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_update_key(struct SNAME *_map_, V val, K new_key) \ + bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_entry **key_entry, **val_entry; \ + struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ \ - val_entry = PFX##_impl_get_entry_by_val(_map_, val); \ + val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ \ if (!val_entry) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ @@ -488,9 +508,9 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) \ goto success; \ \ - if (PFX##_impl_get_entry_by_key(_map_, new_key) != NULL) \ + if (CMC_(PFX, _impl_get_entry_by_key)(_map_, new_key) != NULL) \ { \ - _map_->flag = cmc_flags.DUPLICATE; \ + _map_->flag = CMC_FLAG_DUPLICATE; \ return false; \ } \ \ @@ -499,30 +519,30 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (!key_entry || *key_entry != *val_entry) \ { \ /* Should never happen */ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ /* Remove entry from key buffer and add it again with new key */ \ - struct SNAME##_entry *to_add = *key_entry; \ + struct CMC_DEF_ENTRY(SNAME) *to_add = *key_entry; \ K tmp_key = to_add->key; \ to_add->key = new_key; \ \ *key_entry = CMC_ENTRY_DELETED; \ \ - if (!PFX##_impl_add_entry_to_key(_map_, to_add)) \ + if (!CMC_(PFX, _impl_add_entry_to_key)(_map_, to_add)) \ { \ /* Revert changes */ \ to_add->key = tmp_key; \ *key_entry = to_add; \ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ success: \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->update) \ _map_->callbacks->update(); \ @@ -530,21 +550,21 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_update_val(struct SNAME *_map_, K key, V new_val) \ + bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_entry **key_entry, **val_entry; \ + struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ \ - key_entry = PFX##_impl_get_entry_by_key(_map_, key); \ + key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ \ if (!key_entry) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ @@ -552,9 +572,9 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) \ goto success; \ \ - if (PFX##_impl_get_entry_by_val(_map_, new_val) != NULL) \ + if (CMC_(PFX, _impl_get_entry_by_val)(_map_, new_val) != NULL) \ { \ - _map_->flag = cmc_flags.DUPLICATE; \ + _map_->flag = CMC_FLAG_DUPLICATE; \ return false; \ } \ \ @@ -563,31 +583,31 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (!val_entry || *val_entry != *key_entry) \ { \ /* Should never happen */ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ /* Remove entry from value buffer and add it again with new value */ \ - struct SNAME##_entry *to_add = *val_entry; \ + struct CMC_DEF_ENTRY(SNAME) *to_add = *val_entry; \ V tmp_val = to_add->value; \ to_add->value = new_val; \ \ *val_entry = CMC_ENTRY_DELETED; \ \ - if (!PFX##_impl_add_entry_to_val(_map_, to_add)) \ + if (!CMC_(PFX, _impl_add_entry_to_val)(_map_, to_add)) \ { \ /* Revert changes */ \ to_add->value = tmp_val; \ *val_entry = to_add; \ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ \ return false; \ } \ \ success: \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->update) \ _map_->callbacks->update(); \ @@ -595,22 +615,22 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_remove_by_key(struct SNAME *_map_, K key, K *out_key, \ - V *out_val) \ + bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, \ + V * out_val) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_entry **key_entry, **val_entry; \ + struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ \ - key_entry = PFX##_impl_get_entry_by_key(_map_, key); \ + key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ \ if (!key_entry) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ @@ -619,7 +639,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (!val_entry || *val_entry != *key_entry) \ { \ /* Should never happen */ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ @@ -634,7 +654,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " *val_entry = CMC_ENTRY_DELETED; \ \ _map_->count--; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->delete) \ _map_->callbacks->delete (); \ @@ -642,22 +662,22 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_remove_by_val(struct SNAME *_map_, V val, K *out_key, \ - V *out_val) \ + bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, \ + V * out_val) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_entry **key_entry, **val_entry; \ + struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ \ - val_entry = PFX##_impl_get_entry_by_val(_map_, val); \ + val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ \ if (!val_entry) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ @@ -666,7 +686,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (!key_entry || *key_entry != *val_entry) \ { \ /* Should never happen */ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ @@ -681,7 +701,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " *val_entry = CMC_ENTRY_DELETED; \ \ _map_->count--; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->delete) \ _map_->callbacks->delete (); \ @@ -689,18 +709,18 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - K PFX##_get_key(struct SNAME *_map_, V val) \ + K CMC_(PFX, _get_key)(struct SNAME * _map_, V val) \ { \ - struct SNAME##_entry **entry = \ - PFX##_impl_get_entry_by_val(_map_, val); \ + struct CMC_DEF_ENTRY(SNAME) **entry = \ + CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ \ if (!entry) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return (V){ 0 }; \ } \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -708,18 +728,18 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return (*entry)->key; \ } \ \ - V PFX##_get_val(struct SNAME *_map_, K key) \ + V CMC_(PFX, _get_val)(struct SNAME * _map_, K key) \ { \ - struct SNAME##_entry **entry = \ - PFX##_impl_get_entry_by_key(_map_, key); \ + struct CMC_DEF_ENTRY(SNAME) **entry = \ + CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ \ if (!entry) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return (V){ 0 }; \ } \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -727,11 +747,11 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return (*entry)->value; \ } \ \ - bool PFX##_contains_key(struct SNAME *_map_, K key) \ + bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key) \ { \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ - bool result = PFX##_impl_get_entry_by_key(_map_, key) != NULL; \ + bool result = CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -739,11 +759,11 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return result; \ } \ \ - bool PFX##_contains_val(struct SNAME *_map_, V val) \ + bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val) \ { \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ - bool result = PFX##_impl_get_entry_by_val(_map_, val) != NULL; \ + bool result = CMC_(PFX, _impl_get_entry_by_val)(_map_, val) != NULL; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -751,39 +771,39 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_map_) \ + bool CMC_(PFX, _empty)(struct SNAME * _map_) \ { \ return _map_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_map_) \ + bool CMC_(PFX, _full)(struct SNAME * _map_) \ { \ return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ } \ \ - size_t PFX##_count(struct SNAME *_map_) \ + size_t CMC_(PFX, _count)(struct SNAME * _map_) \ { \ return _map_->count; \ } \ \ - size_t PFX##_capacity(struct SNAME *_map_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ { \ return _map_->capacity; \ } \ \ - double PFX##_load(struct SNAME *_map_) \ + double CMC_(PFX, _load)(struct SNAME * _map_) \ { \ return _map_->load; \ } \ \ - int PFX##_flag(struct SNAME *_map_) \ + int CMC_(PFX, _flag)(struct SNAME * _map_) \ { \ return _map_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_map_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ { \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->capacity == capacity) \ goto success; \ @@ -794,52 +814,52 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " /* Prevent integer overflow */ \ if (capacity >= UINTMAX_MAX * _map_->load) \ { \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ /* Calculate required capacity based on the prime numbers */ \ - size_t new_cap = PFX##_impl_calculate_size(capacity); \ + size_t new_cap = CMC_(PFX, _impl_calculate_size)(capacity); \ \ /* Not possible to shrink with current available prime numbers */ \ if (new_cap < _map_->count / _map_->load) \ { \ - _map_->flag = cmc_flags.INVALID; \ + _map_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ /* No callbacks since _new_map_ is just a temporary hashtable */ \ struct SNAME *_new_map_ = \ - PFX##_new_custom(capacity, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ + CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, NULL); \ \ if (!_new_map_) \ { \ - _map_->flag = cmc_flags.ALLOC; \ + _map_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ for (size_t i = 0; i < _map_->capacity; i++) \ { \ - struct SNAME##_entry *scan = _map_->buffer[i][0]; \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ \ if (scan && scan != CMC_ENTRY_DELETED) \ { \ - struct SNAME##_entry **e1 = \ - PFX##_impl_add_entry_to_key(_new_map_, scan); \ - struct SNAME##_entry **e2 = \ - PFX##_impl_add_entry_to_val(_new_map_, scan); \ + struct CMC_DEF_ENTRY(SNAME) **e1 = \ + CMC_(PFX, _impl_add_entry_to_key)(_new_map_, scan); \ + struct CMC_DEF_ENTRY(SNAME) **e2 = \ + CMC_(PFX, _impl_add_entry_to_val)(_new_map_, scan); \ \ if (!e1 || !e2) \ { \ /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \ - _new_map_->f_val = &(struct SNAME##_fval){ NULL }; \ + _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ + _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ \ _map_->alloc->free(_new_map_->buffer); \ _map_->alloc->free(_new_map_); \ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ \ return false; \ } \ @@ -851,18 +871,18 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " if (_map_->count != _new_map_->count) \ { \ /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \ - _new_map_->f_val = &(struct SNAME##_fval){ NULL }; \ + _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ + _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ \ _map_->alloc->free(_new_map_->buffer); \ _map_->alloc->free(_new_map_); \ \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ \ return false; \ } \ \ - struct SNAME##_entry *(*tmp_buff)[2] = _map_->buffer; \ + struct CMC_DEF_ENTRY(SNAME) * (*tmp_buff)[2] = _map_->buffer; \ \ _map_->buffer = _new_map_->buffer; \ _map_->capacity = _new_map_->capacity; \ @@ -878,22 +898,22 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ { \ /* TODO this function can be optimized */ \ - struct SNAME *result = PFX##_new_custom( \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ _map_->capacity * _map_->load, _map_->load, _map_->f_key, \ _map_->f_val, _map_->alloc, _map_->callbacks); \ \ if (!result) \ { \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ for (size_t i = 0; i < _map_->capacity; i++) \ { \ - struct SNAME##_entry *scan = _map_->buffer[i][0]; \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ \ if (scan && scan != CMC_ENTRY_DELETED) \ { \ @@ -911,25 +931,25 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " tmp_val = scan->value; \ \ /* TODO treat the possible errors */ \ - struct SNAME##_entry *entry = \ - PFX##_impl_new_entry(result, tmp_key, tmp_val); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_new_entry)(result, tmp_key, tmp_val); \ \ - PFX##_impl_add_entry_to_key(result, entry); \ - PFX##_impl_add_entry_to_val(result, entry); \ + CMC_(PFX, _impl_add_entry_to_key)(result, entry); \ + CMC_(PFX, _impl_add_entry_to_val)(result, entry); \ \ result->count++; \ } \ } \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ { \ - _map1_->flag = cmc_flags.OK; \ - _map2_->flag = cmc_flags.OK; \ + _map1_->flag = CMC_FLAG_OK; \ + _map2_->flag = CMC_FLAG_OK; \ \ if (_map1_->count != _map2_->count) \ return false; \ @@ -950,12 +970,12 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ for (size_t i = 0; i < _mapA_->capacity; i++) \ { \ - struct SNAME##_entry *scan = _mapA_->buffer[i][0]; \ + struct CMC_DEF_ENTRY(SNAME) *scan = _mapA_->buffer[i][0]; \ \ if (scan && scan != CMC_ENTRY_DELETED) \ { \ - struct SNAME##_entry **entry_B = \ - PFX##_impl_get_entry_by_key(_mapB_, scan->key); \ + struct CMC_DEF_ENTRY(SNAME) **entry_B = \ + CMC_(PFX, _impl_get_entry_by_key)(_mapB_, scan->key); \ \ if (!entry_B) \ return false; \ @@ -968,24 +988,24 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_map_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ { \ struct cmc_string str; \ struct SNAME *m_ = _map_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashbidimap, \ - #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \ - m_->alloc, m_->callbacks); \ + int n = snprintf( \ + str.s, cmc_string_len, cmc_cmc_string_fmt_hashbidimap, #SNAME, #K, \ + #V, m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, \ + m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_map_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ { \ for (size_t i = 0; i < _map_->capacity; i++) \ { \ - struct SNAME##_entry *target = _map_->buffer[i][0]; \ + struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[i][0]; \ \ if (target && target != CMC_ENTRY_DELETED) \ { \ @@ -998,37 +1018,38 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target) \ { \ - struct SNAME##_iter *iter = \ - target->alloc->malloc(sizeof(struct SNAME##_iter)); \ + struct CMC_DEF_ITER(SNAME) *iter = \ + target->alloc->malloc(sizeof(struct CMC_DEF_ITER(SNAME))); \ \ if (!iter) \ return NULL; \ \ - PFX##_iter_init(iter, target); \ + CMC_(PFX, _iter_init)(iter, target); \ \ return iter; \ } \ \ - void PFX##_iter_free(struct SNAME##_iter *iter) \ + void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ iter->target->alloc->free(iter); \ } \ \ - void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \ + void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, \ + struct SNAME * target) \ { \ - memset(iter, 0, sizeof(struct SNAME##_iter)); \ + memset(iter, 0, sizeof(struct CMC_DEF_ITER(SNAME))); \ \ iter->target = target; \ iter->start = true; \ - iter->end = PFX##_empty(target); \ + iter->end = CMC_(PFX, _empty)(target); \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ for (size_t i = 0; i < target->capacity; i++) \ { \ - struct SNAME##_entry *tmp = target->buffer[i][0]; \ + struct CMC_DEF_ENTRY(SNAME) *tmp = target->buffer[i][0]; \ \ if (tmp != NULL && tmp != CMC_ENTRY_DELETED) \ { \ @@ -1041,7 +1062,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ for (size_t i = target->capacity; i > 0; i--) \ { \ - struct SNAME##_entry *tmp = target->buffer[i - 1][0]; \ + struct CMC_DEF_ENTRY(SNAME) *tmp = target->buffer[i - 1][0]; \ \ if (tmp != NULL && tmp != CMC_ENTRY_DELETED) \ { \ @@ -1052,19 +1073,19 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " } \ } \ \ - bool PFX##_iter_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - void PFX##_iter_to_start(struct SNAME##_iter *iter) \ + void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->first; \ iter->index = 0; \ @@ -1073,9 +1094,9 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " } \ } \ \ - void PFX##_iter_to_end(struct SNAME##_iter *iter) \ + void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->last; \ iter->index = iter->target->count - 1; \ @@ -1084,7 +1105,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " } \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -1095,9 +1116,10 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ - struct SNAME##_entry *scan = iter->target->buffer[iter->cursor][0]; \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + iter->target->buffer[iter->cursor][0]; \ \ iter->index++; \ \ @@ -1113,7 +1135,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -1124,9 +1146,10 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ - struct SNAME##_entry *scan = iter->target->buffer[iter->cursor][0]; \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + iter->target->buffer[iter->cursor][0]; \ \ iter->index--; \ \ @@ -1143,7 +1166,8 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -1158,13 +1182,14 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_next(iter); \ + CMC_(PFX, _iter_next)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -1179,58 +1204,59 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_prev(iter); \ + CMC_(PFX, _iter_prev)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator was able to be positioned at */ \ /* the given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ \ return true; \ } \ \ - K PFX##_iter_key(struct SNAME##_iter *iter) \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ { \ - iter->target->flag = cmc_flags.EMPTY; \ + iter->target->flag = CMC_FLAG_EMPTY; \ return (K){ 0 }; \ } \ \ return iter->target->buffer[iter->cursor][0]->key; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ { \ - iter->target->flag = cmc_flags.EMPTY; \ + iter->target->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ return iter->target->buffer[iter->cursor][0]->value; \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->index; \ } \ \ - static struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, \ - K key, V value) \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ { \ - struct SNAME##_entry *entry = \ - _map_->alloc->malloc(sizeof(struct SNAME##_entry)); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \ \ if (!entry) \ return NULL; \ @@ -1245,13 +1271,13 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return entry; \ } \ \ - static struct SNAME##_entry **PFX##_impl_get_entry_by_key( \ - struct SNAME *_map_, K key) \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key) \ { \ size_t hash = _map_->f_key->hash(key); \ size_t pos = hash % _map_->capacity; \ \ - struct SNAME##_entry *target = _map_->buffer[pos][0]; \ + struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][0]; \ \ while (target != NULL) \ { \ @@ -1266,13 +1292,13 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return NULL; \ } \ \ - static struct SNAME##_entry **PFX##_impl_get_entry_by_val( \ - struct SNAME *_map_, V val) \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val) \ { \ size_t hash = _map_->f_val->hash(val); \ size_t pos = hash % _map_->capacity; \ \ - struct SNAME##_entry *target = _map_->buffer[pos][1]; \ + struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][1]; \ \ while (target != NULL) \ { \ @@ -1287,16 +1313,17 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return NULL; \ } \ \ - static struct SNAME##_entry **PFX##_impl_add_entry_to_key( \ - struct SNAME *_map_, struct SNAME##_entry *entry) \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_add_entry_to_key)( \ + struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \ { \ - struct SNAME##_entry **to_return = NULL; \ + struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \ \ size_t hash = _map_->f_key->hash(entry->key); \ size_t original_pos = hash % _map_->capacity; \ size_t pos = original_pos; \ \ - struct SNAME##_entry **scan = \ + struct CMC_DEF_ENTRY(SNAME) **scan = \ &(_map_->buffer[hash % _map_->capacity][0]); \ \ if (*scan == NULL) \ @@ -1336,7 +1363,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ entry->ref[0] = scan; \ \ - struct SNAME##_entry *_tmp_ = *scan; \ + struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \ *scan = entry; \ entry = _tmp_; \ } \ @@ -1346,16 +1373,17 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return NULL; \ } \ \ - static struct SNAME##_entry **PFX##_impl_add_entry_to_val( \ - struct SNAME *_map_, struct SNAME##_entry *entry) \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_add_entry_to_val)( \ + struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \ { \ - struct SNAME##_entry **to_return = NULL; \ + struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \ \ size_t hash = _map_->f_val->hash(entry->value); \ size_t original_pos = hash % _map_->capacity; \ size_t pos = original_pos; \ \ - struct SNAME##_entry **scan = \ + struct CMC_DEF_ENTRY(SNAME) **scan = \ &(_map_->buffer[hash % _map_->capacity][1]); \ \ if (*scan == NULL) \ @@ -1395,7 +1423,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ entry->ref[1] = scan; \ \ - struct SNAME##_entry *_tmp_ = *scan; \ + struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \ *scan = entry; \ entry = _tmp_; \ } \ @@ -1405,7 +1433,7 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return NULL; \ } \ \ - static size_t PFX##_impl_calculate_size(size_t required) \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ { \ const size_t count = \ sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ @@ -1420,23 +1448,25 @@ static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " return cmc_hashtable_primes[i]; \ } \ \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_map_) \ + static struct CMC_DEF_ITER(SNAME) \ + CMC_(PFX, _impl_it_start)(struct SNAME * _map_) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ - PFX##_iter_init(&iter, _map_); \ + CMC_(PFX, _iter_init)(&iter, _map_); \ \ return iter; \ } \ \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_) \ + static struct CMC_DEF_ITER(SNAME) \ + CMC_(PFX, _impl_it_end)(struct SNAME * _map_) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ - PFX##_iter_init(&iter, _map_); \ - PFX##_iter_to_end(&iter); \ + CMC_(PFX, _iter_init)(&iter, _map_); \ + CMC_(PFX, _iter_to_end)(&iter); \ \ return iter; \ } -#endif /* CMC_HASHBIDIMAP_H */ +#endif /* CMC_CMC_HASHBIDIMAP_H */ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 33bafb3..d64dcaf 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -16,8 +16,8 @@ * hashtable with linear probing and robin hood hashing. */ -#ifndef CMC_HASHMAP_H -#define CMC_HASHMAP_H +#ifndef CMC_CMC_HASHMAP_H +#define CMC_CMC_HASHMAP_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -33,38 +33,43 @@ * HashMap Specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *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 }"; +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 }"; -#define CMC_GENERATE_HASHMAP(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMAP_SOURCE(PFX, SNAME, K, V) +/** + * Core HashMap implementation + */ +#define CMC_CMC_HASHMAP_CORE(BODY) \ + CMC_CMC_HASHMAP_CORE_HEADER(BODY) \ + CMC_CMC_HASHMAP_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_HASHMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMAP_HEADER(PFX, SNAME, K, V) +#define CMC_CMC_HASHMAP_CORE_HEADER(BODY) \ + CMC_CMC_HASHMAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_HASHMAP_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMAP_SOURCE(PFX, SNAME, K, V) +#define CMC_CMC_HASHMAP_CORE_SOURCE(BODY) \ + CMC_CMC_HASHMAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHMAP_HEADER(PFX, SNAME, K, V) \ +#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \ \ /* Hashmap Structure */ \ struct SNAME \ { \ /* Array of Entries */ \ - struct SNAME##_entry *buffer; \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ \ /* Current array capacity */ \ size_t capacity; \ @@ -79,10 +84,10 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> " int flag; \ \ /* Key function table */ \ - struct SNAME##_fkey *f_key; \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ \ /* Value function table */ \ - struct SNAME##_fval *f_val; \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ \ /* Custom allocation functions */ \ struct cmc_alloc_node *alloc; \ @@ -92,7 +97,7 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> " }; \ \ /* Hashmap Entry */ \ - struct SNAME##_entry \ + struct CMC_DEF_ENTRY(SNAME) \ { \ /* Entry Key */ \ K key; \ @@ -109,7 +114,7 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> " }; \ \ /* Key struct function table */ \ - struct SNAME##_fkey \ + struct CMC_DEF_FKEY(SNAME) \ { \ /* Comparator function */ \ int (*cmp)(K, K); \ @@ -131,7 +136,7 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> " }; \ \ /* Value struct function table */ \ - struct SNAME##_fval \ + struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ int (*cmp)(V, V); \ @@ -153,7 +158,7 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> " }; \ \ /* Hashmap Iterator */ \ - struct SNAME##_iter \ + struct CMC_DEF_ITER(SNAME) \ { \ /* Target hashmap */ \ struct SNAME *target; \ @@ -179,1046 +184,1012 @@ static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> " \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - struct SNAME PFX##_init(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val); \ - struct SNAME PFX##_init_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_map_); \ - void PFX##_free(struct SNAME *_map_); \ - void PFX##_release(struct SNAME _map_); \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_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); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ + void CMC_(PFX, _release)(struct SNAME _map_); \ /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_map_, K key, V value); \ - bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value); \ - bool PFX##_remove(struct SNAME *_map_, K key, V *out_value); \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ + V * old_value); \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ /* Element Access */ \ - bool PFX##_max(struct SNAME *_map_, K *key, V *value); \ - bool PFX##_min(struct SNAME *_map_, K *key, V *value); \ - V PFX##_get(struct SNAME *_map_, K key); \ - V *PFX##_get_ref(struct SNAME *_map_, K key); \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ /* Collection State */ \ - bool PFX##_contains(struct SNAME *_map_, K key); \ - bool PFX##_empty(struct SNAME *_map_); \ - bool PFX##_full(struct SNAME *_map_); \ - size_t PFX##_count(struct SNAME *_map_); \ - size_t PFX##_capacity(struct SNAME *_map_); \ - double PFX##_load(struct SNAME *_map_); \ - int PFX##_flag(struct SNAME *_map_); \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + bool CMC_(PFX, _full)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ + double CMC_(PFX, _load)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_map_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_); \ - bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_map_); \ - bool PFX##_print(struct SNAME *_map_, FILE *fptr); \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ \ /* Iterator Functions */ \ /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ /* Iterator Access */ \ - K PFX##_iter_key(struct SNAME##_iter *iter); \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHMAP_SOURCE(PFX, SNAME, K, V) \ - \ - /* Implementation Detail Functions */ \ - static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, \ - K key); \ - static size_t PFX##_impl_calculate_size(size_t required); \ - \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val) \ - { \ - return PFX##_new_custom(capacity, load, f_key, f_val, NULL, NULL); \ - } \ - \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ - { \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_key || !f_val) \ - return NULL; \ - \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \ - \ - if (!_map_->buffer) \ - { \ - alloc->free(_map_); \ - return NULL; \ - } \ - \ - _map_->count = 0; \ - _map_->capacity = real_capacity; \ - _map_->load = load; \ - _map_->flag = cmc_flags.OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->alloc = alloc; \ - _map_->callbacks = callbacks; \ - \ - return _map_; \ - } \ - struct SNAME PFX##_init(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val) \ - { \ - return PFX##_init_custom(capacity, load, f_key, f_val, NULL, NULL); \ - } \ - \ - struct SNAME PFX##_init_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *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 = 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_flags.OK; \ - _map_.f_key = f_key; \ - _map_.f_val = f_val; \ - _map_.alloc = alloc; \ - _map_.callbacks = callbacks; \ - \ - return _map_; \ - } \ - \ - void PFX##_clear(struct SNAME *_map_) \ - { \ - if (_map_->f_key->free || _map_->f_val->free) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct SNAME##_entry *entry = &(_map_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(entry->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(entry->value); \ - } \ - } \ - } \ - \ - memset(_map_->buffer, 0, \ - sizeof(struct SNAME##_entry) * _map_->capacity); \ - \ - _map_->count = 0; \ - _map_->flag = cmc_flags.OK; \ - } \ - \ - void PFX##_free(struct SNAME *_map_) \ - { \ - if (_map_->f_key->free || _map_->f_val->free) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct SNAME##_entry *entry = &(_map_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(entry->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(entry->value); \ - } \ - } \ - } \ - \ - _map_->alloc->free(_map_->buffer); \ - _map_->alloc->free(_map_); \ - } \ - \ - void PFX##_release(struct SNAME _map_) \ - { \ - if (_map_.f_key->free || _map_.f_val->free) \ - { \ - for (size_t i = 0; i < _map_.capacity; i++) \ - { \ - struct SNAME##_entry *entry = &(_map_.buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (_map_.f_key->free) \ - _map_.f_key->free(entry->key); \ - if (_map_.f_val->free) \ - _map_.f_val->free(entry->value); \ - } \ - } \ - } \ - \ - _map_.alloc->free(_map_.buffer); \ - } \ - \ - void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ - { \ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ - \ - _map_->callbacks = callbacks; \ - \ - _map_->flag = cmc_flags.OK; \ - } \ - \ - bool PFX##_insert(struct SNAME *_map_, K key, V value) \ - { \ - if (PFX##_full(_map_)) \ - { \ - if (!PFX##_resize(_map_, _map_->capacity + 1)) \ - return false; \ - } \ - \ - if (PFX##_impl_get_entry(_map_, key) != NULL) \ - { \ - _map_->flag = cmc_flags.DUPLICATE; \ - return false; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - size_t original_pos = hash % _map_->capacity; \ - size_t pos = original_pos; \ - \ - struct SNAME##_entry *target = &(_map_->buffer[pos]); \ - \ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->key = key; \ - target->value = value; \ - target->dist = 0; \ - target->state = CMC_ES_FILLED; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - target = &(_map_->buffer[pos % _map_->capacity]); \ - \ - if (target->state == CMC_ES_EMPTY || \ - target->state == CMC_ES_DELETED) \ - { \ - target->key = key; \ - target->value = value; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ - \ - break; \ - } \ - else if (target->dist < pos - original_pos) \ - { \ - K tmp_k = target->key; \ - V tmp_v = target->value; \ - size_t tmp_dist = target->dist; \ - \ - target->key = key; \ - target->value = value; \ - target->dist = pos - original_pos; \ - \ - key = tmp_k; \ - value = tmp_v; \ - original_pos = pos - tmp_dist; \ - } \ - } \ - } \ - \ - _map_->count++; \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return false; \ - } \ - \ - if (old_value) \ - *old_value = entry->value; \ - \ - entry->value = new_value; \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool PFX##_remove(struct SNAME *_map_, K key, V *out_value) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_entry *result = PFX##_impl_get_entry(_map_, key); \ - \ - if (result == NULL) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return false; \ - } \ - \ - if (out_value) \ - *out_value = result->value; \ - \ - result->key = (K){ 0 }; \ - result->value = (V){ 0 }; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ - \ - _map_->count--; \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool PFX##_max(struct SNAME *_map_, K *key, V *value) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map_); \ - \ - K max_key = PFX##_iter_key(&iter); \ - V max_val = PFX##_iter_value(&iter); \ - \ - PFX##_iter_next(&iter); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - K iter_key = PFX##_iter_key(&iter); \ - V iter_val = PFX##_iter_value(&iter); \ - \ - if (_map_->f_key->cmp(iter_key, max_key) > 0) \ - { \ - max_key = iter_key; \ - max_val = iter_val; \ - } \ - } \ - \ - if (key) \ - *key = max_key; \ - if (value) \ - *value = max_val; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool PFX##_min(struct SNAME *_map_, K *key, V *value) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map_); \ - \ - K min_key = PFX##_iter_key(&iter); \ - V min_val = PFX##_iter_value(&iter); \ - \ - PFX##_iter_next(&iter); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - K iter_key = PFX##_iter_key(&iter); \ - V iter_val = PFX##_iter_value(&iter); \ - \ - if (_map_->f_key->cmp(iter_key, min_key) < 0) \ - { \ - min_key = iter_key; \ - min_val = iter_val; \ - } \ - } \ - \ - if (key) \ - *key = min_key; \ - if (value) \ - *value = min_val; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - V PFX##_get(struct SNAME *_map_, K key) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return (V){ 0 }; \ - } \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return entry->value; \ - } \ - \ - V *PFX##_get_ref(struct SNAME *_map_, K key) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return NULL; \ - } \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return &(entry->value); \ - } \ - \ - bool PFX##_contains(struct SNAME *_map_, K key) \ - { \ - _map_->flag = cmc_flags.OK; \ - \ - bool result = PFX##_impl_get_entry(_map_, key) != NULL; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool PFX##_empty(struct SNAME *_map_) \ - { \ - return _map_->count == 0; \ - } \ - \ - bool PFX##_full(struct SNAME *_map_) \ - { \ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ - } \ - \ - size_t PFX##_count(struct SNAME *_map_) \ - { \ - return _map_->count; \ - } \ - \ - size_t PFX##_capacity(struct SNAME *_map_) \ - { \ - return _map_->capacity; \ - } \ - \ - double PFX##_load(struct SNAME *_map_) \ - { \ - return _map_->load; \ - } \ - \ - int PFX##_flag(struct SNAME *_map_) \ - { \ - return _map_->flag; \ - } \ - \ - bool PFX##_resize(struct SNAME *_map_, size_t capacity) \ - { \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->capacity == capacity) \ - goto success; \ - \ - if (_map_->capacity > capacity / _map_->load) \ - goto success; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _map_->load) \ - { \ - _map_->flag = cmc_flags.ERROR; \ - return false; \ - } \ - \ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = PFX##_impl_calculate_size(capacity); \ - \ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _map_->count / _map_->load) \ - { \ - _map_->flag = cmc_flags.INVALID; \ - return false; \ - } \ - \ - /* No callbacks since _new_map_ is just a temporary hashtable */ \ - struct SNAME *_new_map_ = \ - PFX##_new_custom(capacity, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ - \ - if (!_new_map_) \ - { \ - _map_->flag = cmc_flags.ALLOC; \ - return false; \ - } \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map_); \ - \ - /* TODO turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - K key = PFX##_iter_key(&iter); \ - V value = PFX##_iter_value(&iter); \ - \ - PFX##_insert(_new_map_, key, value); \ - } \ - \ - /* Unlikely */ \ - if (_map_->count != _new_map_->count) \ - { \ - PFX##_free(_new_map_); \ - \ - _map_->flag = cmc_flags.ERROR; \ - return false; \ - } \ - \ - struct SNAME##_entry *tmp_b = _map_->buffer; \ - _map_->buffer = _new_map_->buffer; \ - _new_map_->buffer = tmp_b; \ - \ - size_t tmp_c = _map_->capacity; \ - _map_->capacity = _new_map_->capacity; \ - _new_map_->capacity = tmp_c; \ - \ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \ - _new_map_->f_val = &(struct SNAME##_fval){ NULL }; \ - \ - PFX##_free(_new_map_); \ - \ - success: \ - \ - if (_map_->callbacks && _map_->callbacks->resize) \ - _map_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_) \ - { \ - struct SNAME *result = PFX##_new_custom( \ - _map_->capacity * _map_->load, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, _map_->callbacks); \ - \ - if (!result) \ - { \ - _map_->flag = cmc_flags.ERROR; \ - return NULL; \ - } \ - \ - if (_map_->f_key->cpy || _map_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct SNAME##_entry *scan = &(_map_->buffer[i]); \ - \ - if (scan->state != CMC_ES_EMPTY) \ - { \ - struct SNAME##_entry *target = &(result->buffer[i]); \ - \ - if (scan->state == CMC_ES_DELETED) \ - target->state = CMC_ES_DELETED; \ - else \ - { \ - target->state = scan->state; \ - target->dist = scan->dist; \ - \ - if (_map_->f_key->cpy) \ - target->key = _map_->f_key->cpy(scan->key); \ - else \ - target->key = scan->key; \ - \ - if (_map_->f_val->cpy) \ - target->value = _map_->f_val->cpy(scan->value); \ - else \ - target->value = scan->value; \ - } \ - } \ - } \ - } \ - else \ - memcpy(result->buffer, _map_->buffer, \ - sizeof(struct SNAME##_entry) * _map_->capacity); \ - \ - result->count = _map_->count; \ - \ - _map_->flag = cmc_flags.OK; \ - \ - return result; \ - } \ - \ - bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \ - { \ - _map1_->flag = cmc_flags.OK; \ - _map2_->flag = cmc_flags.OK; \ - \ - if (_map1_->count != _map2_->count) \ - return false; \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map1_); \ - \ - /* TODO optimize this loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - struct SNAME##_entry *entry = \ - PFX##_impl_get_entry(_map2_, PFX##_iter_key(&iter)); \ - \ - if (entry == NULL) \ - return false; \ - \ - if (_map1_->f_val->cmp(entry->value, PFX##_iter_value(&iter)) != \ - 0) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string PFX##_to_string(struct SNAME *_map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmap, \ - #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \ - m_->alloc, m_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool PFX##_print(struct SNAME *_map_, FILE *fptr) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct SNAME##_entry *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; \ - } \ - } \ - \ - return true; \ - } \ - \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ - { \ - struct SNAME##_iter iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = PFX##_empty(target); \ - \ - if (!PFX##_empty(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ - { \ - struct SNAME##_iter iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = PFX##_empty(target); \ - iter.end = true; \ - \ - if (!PFX##_empty(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->start; \ - } \ - \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->end; \ - } \ - \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ - { \ - if (!PFX##_empty(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ - { \ - if (!PFX##_empty(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \ - \ - iter->index++; \ - \ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \ - \ - iter->index--; \ - \ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - PFX##_iter_next(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - PFX##_iter_prev(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ - else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - K PFX##_iter_key(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return (K){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].key; \ - } \ - \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].value; \ - } \ - \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor].value); \ - } \ - \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ - { \ - return iter->index; \ - } \ - \ - static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, \ - K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - size_t pos = hash % _map_->capacity; \ - \ - struct SNAME##_entry *target = &(_map_->buffer[pos]); \ - \ - while (target->state == CMC_ES_FILLED || \ - target->state == CMC_ES_DELETED) \ - { \ - if (_map_->f_key->cmp(target->key, key) == 0) \ - return target; \ - \ - pos++; \ - target = &(_map_->buffer[pos % _map_->capacity]); \ - } \ - \ - return NULL; \ - } \ - \ - static size_t PFX##_impl_calculate_size(size_t required) \ - { \ - const size_t count = \ - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ - \ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ - \ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ - \ - return cmc_hashtable_primes[i]; \ +#define CMC_CMC_HASHMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ + \ + /* Implementation Detail Functions */ \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ + \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, \ + NULL); \ + } \ + \ + struct SNAME *CMC_(PFX, _new_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) \ + { \ + if (capacity == 0 || load <= 0 || load >= 1) \ + return NULL; \ + \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ + \ + if (!f_key || !f_val) \ + return NULL; \ + \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_map_) \ + return NULL; \ + \ + _map_->buffer = \ + alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ + \ + if (!_map_->buffer) \ + { \ + alloc->free(_map_); \ + return NULL; \ + } \ + \ + _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_; \ + } \ + \ + void CMC_(PFX, _clear)(struct SNAME * _map_) \ + { \ + if (_map_->f_key->free || _map_->f_val->free) \ + { \ + 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->free) \ + _map_->f_key->free(entry->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(entry->value); \ + } \ + } \ + } \ + \ + memset(_map_->buffer, 0, \ + sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \ + \ + _map_->count = 0; \ + _map_->flag = CMC_FLAG_OK; \ + } \ + \ + void CMC_(PFX, _free)(struct SNAME * _map_) \ + { \ + if (_map_->f_key->free || _map_->f_val->free) \ + { \ + 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->free) \ + _map_->f_key->free(entry->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(entry->value); \ + } \ + } \ + } \ + \ + _map_->alloc->free(_map_->buffer); \ + _map_->alloc->free(_map_); \ + } \ + \ + void CMC_(PFX, _release)(struct SNAME _map_) \ + { \ + if (_map_.f_key->free || _map_.f_val->free) \ + { \ + 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->free) \ + _map_.f_key->free(entry->key); \ + if (_map_.f_val->free) \ + _map_.f_val->free(entry->value); \ + } \ + } \ + } \ + \ + _map_.alloc->free(_map_.buffer); \ + } \ + \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + if (!alloc) \ + _map_->alloc = &cmc_alloc_node_default; \ + else \ + _map_->alloc = alloc; \ + \ + _map_->callbacks = callbacks; \ + \ + _map_->flag = CMC_FLAG_OK; \ + } \ + \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ + { \ + if (CMC_(PFX, _full)(_map_)) \ + { \ + if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ + return false; \ + } \ + \ + if (CMC_(PFX, _impl_get_entry)(_map_, key) != NULL) \ + { \ + _map_->flag = CMC_FLAG_DUPLICATE; \ + return false; \ + } \ + \ + size_t hash = _map_->f_key->hash(key); \ + size_t original_pos = hash % _map_->capacity; \ + size_t pos = original_pos; \ + \ + struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \ + \ + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ + { \ + target->key = key; \ + target->value = value; \ + target->dist = 0; \ + target->state = CMC_ES_FILLED; \ + } \ + else \ + { \ + while (true) \ + { \ + pos++; \ + target = &(_map_->buffer[pos % _map_->capacity]); \ + \ + if (target->state == CMC_ES_EMPTY || \ + target->state == CMC_ES_DELETED) \ + { \ + target->key = key; \ + target->value = value; \ + target->dist = pos - original_pos; \ + target->state = CMC_ES_FILLED; \ + \ + break; \ + } \ + else if (target->dist < pos - original_pos) \ + { \ + K tmp_k = target->key; \ + V tmp_v = target->value; \ + size_t tmp_dist = target->dist; \ + \ + target->key = key; \ + target->value = value; \ + target->dist = pos - original_pos; \ + \ + key = tmp_k; \ + value = tmp_v; \ + original_pos = pos - tmp_dist; \ + } \ + } \ + } \ + \ + _map_->count++; \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->create) \ + _map_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ + V * old_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_map_, key); \ + \ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ + \ + if (old_value) \ + *old_value = entry->value; \ + \ + entry->value = new_value; \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *result = \ + CMC_(PFX, _impl_get_entry)(_map_, key); \ + \ + if (result == NULL) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ + \ + if (out_value) \ + *out_value = result->value; \ + \ + result->key = (K){ 0 }; \ + result->value = (V){ 0 }; \ + result->dist = 0; \ + result->state = CMC_ES_DELETED; \ + \ + _map_->count--; \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + \ + K max_key = CMC_(PFX, _iter_key)(&iter); \ + V max_val = CMC_(PFX, _iter_value)(&iter); \ + \ + CMC_(PFX, _iter_next)(&iter); \ + \ + /* TODO Turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K iter_key = CMC_(PFX, _iter_key)(&iter); \ + V iter_val = CMC_(PFX, _iter_value)(&iter); \ + \ + if (_map_->f_key->cmp(iter_key, max_key) > 0) \ + { \ + max_key = iter_key; \ + max_val = iter_val; \ + } \ + } \ + \ + if (key) \ + *key = max_key; \ + if (value) \ + *value = max_val; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + \ + K min_key = CMC_(PFX, _iter_key)(&iter); \ + V min_val = CMC_(PFX, _iter_value)(&iter); \ + \ + CMC_(PFX, _iter_next)(&iter); \ + \ + /* TODO Turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K iter_key = CMC_(PFX, _iter_key)(&iter); \ + V iter_val = CMC_(PFX, _iter_value)(&iter); \ + \ + if (_map_->f_key->cmp(iter_key, min_key) < 0) \ + { \ + min_key = iter_key; \ + min_val = iter_val; \ + } \ + } \ + \ + if (key) \ + *key = min_key; \ + if (value) \ + *value = min_val; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_map_, key); \ + \ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return (V){ 0 }; \ + } \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return entry->value; \ + } \ + \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_map_, key); \ + \ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return NULL; \ + } \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return &(entry->value); \ + } \ + \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ + { \ + _map_->flag = CMC_FLAG_OK; \ + \ + bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _empty)(struct SNAME * _map_) \ + { \ + return _map_->count == 0; \ + } \ + \ + bool CMC_(PFX, _full)(struct SNAME * _map_) \ + { \ + return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ + } \ + \ + size_t CMC_(PFX, _count)(struct SNAME * _map_) \ + { \ + return _map_->count; \ + } \ + \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ + { \ + return _map_->capacity; \ + } \ + \ + double CMC_(PFX, _load)(struct SNAME * _map_) \ + { \ + return _map_->load; \ + } \ + \ + int CMC_(PFX, _flag)(struct SNAME * _map_) \ + { \ + return _map_->flag; \ + } \ + \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ + { \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->capacity == capacity) \ + goto success; \ + \ + if (_map_->capacity > capacity / _map_->load) \ + goto success; \ + \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * _map_->load) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ + \ + /* Calculate required capacity based on the prime numbers */ \ + size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ + \ + /* Not possible to shrink with current available prime numbers */ \ + if (theoretical_size < _map_->count / _map_->load) \ + { \ + _map_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + /* No callbacks since _new_map_ is just a temporary hashtable */ \ + struct SNAME *_new_map_ = \ + CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, NULL); \ + \ + if (!_new_map_) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + \ + /* TODO turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K key = CMC_(PFX, _iter_key)(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + CMC_(PFX, _insert)(_new_map_, key, value); \ + } \ + \ + /* Unlikely */ \ + if (_map_->count != _new_map_->count) \ + { \ + CMC_(PFX, _free)(_new_map_); \ + \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *tmp_b = _map_->buffer; \ + _map_->buffer = _new_map_->buffer; \ + _new_map_->buffer = tmp_b; \ + \ + size_t tmp_c = _map_->capacity; \ + _map_->capacity = _new_map_->capacity; \ + _new_map_->capacity = tmp_c; \ + \ + /* Prevent the map from freeing the data */ \ + _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ + _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ + \ + CMC_(PFX, _free)(_new_map_); \ + \ + success: \ + \ + if (_map_->callbacks && _map_->callbacks->resize) \ + _map_->callbacks->resize(); \ + \ + return true; \ + } \ + \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _map_->capacity * _map_->load, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, _map_->callbacks); \ + \ + if (!result) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ + \ + if (_map_->f_key->cpy || _map_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = &(_map_->buffer[i]); \ + \ + if (scan->state != CMC_ES_EMPTY) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *target = \ + &(result->buffer[i]); \ + \ + if (scan->state == CMC_ES_DELETED) \ + target->state = CMC_ES_DELETED; \ + else \ + { \ + target->state = scan->state; \ + target->dist = scan->dist; \ + \ + if (_map_->f_key->cpy) \ + target->key = _map_->f_key->cpy(scan->key); \ + else \ + target->key = scan->key; \ + \ + if (_map_->f_val->cpy) \ + target->value = _map_->f_val->cpy(scan->value); \ + else \ + target->value = scan->value; \ + } \ + } \ + } \ + } \ + else \ + memcpy(result->buffer, _map_->buffer, \ + sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \ + \ + result->count = _map_->count; \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ + { \ + _map1_->flag = CMC_FLAG_OK; \ + _map2_->flag = CMC_FLAG_OK; \ + \ + if (_map1_->count != _map2_->count) \ + return false; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ + \ + /* TODO optimize this loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)( \ + _map2_, CMC_(PFX, _iter_key)(&iter)); \ + \ + if (entry == NULL) \ + return false; \ + \ + if (_map1_->f_val->cmp(entry->value, \ + CMC_(PFX, _iter_value)(&iter)) != 0) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ + { \ + struct cmc_string str; \ + struct SNAME *m_ = _map_; \ + \ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmap, \ + #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \ + m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \ + m_->alloc, m_->callbacks); \ + \ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ + { \ + 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; \ + } \ + } \ + \ + return true; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.first; \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ + \ + iter->index++; \ + \ + while (1) \ + { \ + iter->cursor++; \ + scan = &(iter->target->buffer[iter->cursor]); \ + \ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ + \ + iter->index--; \ + \ + while (1) \ + { \ + iter->cursor--; \ + scan = &(iter->target->buffer[iter->cursor]); \ + \ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (K){ 0 }; \ + \ + return iter->target->buffer[iter->cursor].key; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor].value; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->target->buffer[iter->cursor].value); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } \ + \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ + { \ + size_t hash = _map_->f_key->hash(key); \ + size_t pos = hash % _map_->capacity; \ + \ + struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \ + \ + while (target->state == CMC_ES_FILLED || \ + target->state == CMC_ES_DELETED) \ + { \ + if (_map_->f_key->cmp(target->key, key) == 0) \ + return target; \ + \ + pos++; \ + target = &(_map_->buffer[pos % _map_->capacity]); \ + } \ + \ + return NULL; \ + } \ + \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ + { \ + const size_t count = \ + sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ + \ + if (cmc_hashtable_primes[count - 1] < required) \ + return required; \ + \ + size_t i = 0; \ + while (cmc_hashtable_primes[i] < required) \ + i++; \ + \ + return cmc_hashtable_primes[i]; \ } -#endif /* CMC_HASHMAP_H */ +#endif /* CMC_CMC_HASHMAP_H */ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index be8c95e..cc4461b 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -41,8 +41,8 @@ * the first key added will be the first to be removed. */ -#ifndef CMC_HASHMULTIMAP_H -#define CMC_HASHMULTIMAP_H +#ifndef CMC_CMC_HASHMULTIMAP_H +#define CMC_CMC_HASHMULTIMAP_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -58,38 +58,45 @@ * HashMultiMap specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_hashmultimap = "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 }"; +static const char *cmc_cmc_string_fmt_hashmultimap = "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 }"; -#define CMC_GENERATE_HASHMULTIMAP(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMULTIMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMULTIMAP_SOURCE(PFX, SNAME, K, V) +/** + * Core HashMultiMap implementation + */ +#define CMC_CMC_HASHMULTIMAP_CORE(BODY) \ + CMC_CMC_HASHMULTIMAP_CORE_HEADER(BODY) \ + CMC_CMC_HASHMULTIMAP_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_HASHMULTIMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMULTIMAP_HEADER(PFX, SNAME, K, V) +#define CMC_CMC_HASHMULTIMAP_CORE_HEADER(BODY) \ + CMC_CMC_HASHMULTIMAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_HASHMULTIMAP_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMULTIMAP_SOURCE(PFX, SNAME, K, V) +#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE(BODY) \ + CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHMULTIMAP_HEADER(PFX, SNAME, K, V) \ +#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ \ /* HashMultimap Structure */ \ struct SNAME \ { \ /* Array of linked list to entries */ \ - struct SNAME##_entry *(*buffer)[2]; \ + struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ \ /* Current array capacity */ \ size_t capacity; \ @@ -104,10 +111,10 @@ static const char *cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " int flag; \ \ /* Key function table */ \ - struct SNAME##_fkey *f_key; \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ \ /* Value function table */ \ - struct SNAME##_fval *f_val; \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ \ /* Custom allocation functions */ \ struct cmc_alloc_node *alloc; \ @@ -117,7 +124,7 @@ static const char *cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " }; \ \ /* HashMultimap Entry */ \ - struct SNAME##_entry \ + struct CMC_DEF_ENTRY(SNAME) \ { \ /* Entry Key */ \ K key; \ @@ -126,14 +133,14 @@ static const char *cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " V value; \ \ /* Next entry on the linked list */ \ - struct SNAME##_entry *next; \ + struct CMC_DEF_ENTRY(SNAME) * next; \ \ /* Previous entry on the linked list */ \ - struct SNAME##_entry *prev; \ + struct CMC_DEF_ENTRY(SNAME) * prev; \ }; \ \ /* Key struct function table */ \ - struct SNAME##_fkey \ + struct CMC_DEF_FKEY(SNAME) \ { \ /* Comparator function */ \ int (*cmp)(K, K); \ @@ -155,7 +162,7 @@ static const char *cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " }; \ \ /* Value struct function table */ \ - struct SNAME##_fval \ + struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ int (*cmp)(V, V); \ @@ -176,13 +183,13 @@ static const char *cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " int (*pri)(V, V); \ }; \ \ - struct SNAME##_iter \ + struct CMC_DEF_ITER(SNAME) \ { \ /* Target hashmultimap */ \ struct SNAME *target; \ \ /* Current entry */ \ - struct SNAME##_entry *curr_entry; \ + struct CMC_DEF_ENTRY(SNAME) * curr_entry; \ \ /* Cursor`s position (index) */ \ size_t cursor; \ @@ -205,1266 +212,1287 @@ static const char *cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_map_); \ - void PFX##_free(struct SNAME *_map_); \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_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); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_map_, K key, V value); \ - bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value); \ - size_t PFX##_update_all(struct SNAME *_map_, K key, V new_value, \ - V **old_values); \ - bool PFX##_remove(struct SNAME *_map_, K key, V *out_value); \ - size_t PFX##_remove_all(struct SNAME *_map_, K key, V **out_values); \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ + V * old_value); \ + size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, \ + V * *old_values); \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ + size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, \ + V * *out_values); \ /* Element Access */ \ - bool PFX##_max(struct SNAME *_map_, K *key, V *value); \ - bool PFX##_min(struct SNAME *_map_, K *key, V *value); \ - V PFX##_get(struct SNAME *_map_, K key); \ - V *PFX##_get_ref(struct SNAME *_map_, K key); \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ /* Collection State */ \ - bool PFX##_contains(struct SNAME *_map_, K key); \ - bool PFX##_empty(struct SNAME *_map_); \ - bool PFX##_full(struct SNAME *_map_); \ - size_t PFX##_count(struct SNAME *_map_); \ - size_t PFX##_key_count(struct SNAME *_map_, K key); \ - size_t PFX##_capacity(struct SNAME *_map_); \ - double PFX##_load(struct SNAME *_map_); \ - int PFX##_flag(struct SNAME *_map_); \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + bool CMC_(PFX, _full)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ + double CMC_(PFX, _load)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_map_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_); \ - bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_map_); \ - bool PFX##_print(struct SNAME *_map_, FILE *fptr); \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ \ /* Iterator Functions */ \ /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ /* Iterator Access */ \ - K PFX##_iter_key(struct SNAME##_iter *iter); \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHMULTIMAP_SOURCE(PFX, SNAME, K, V) \ - \ - /* Implementation Detail Functions */ \ - struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, K key, \ - V value); \ - struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, K key); \ - size_t PFX##_impl_key_count(struct SNAME *_map_, K key); \ - size_t PFX##_impl_calculate_size(size_t required); \ - \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity == 0 || load <= 0) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_key || !f_val) \ - return NULL; \ - \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry *[2])); \ - \ - if (!_map_->buffer) \ - { \ - alloc->free(_map_); \ - return NULL; \ - } \ - \ - _map_->count = 0; \ - _map_->capacity = real_capacity; \ - _map_->load = load; \ - _map_->flag = cmc_flags.OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->alloc = alloc; \ - _map_->callbacks = NULL; \ - \ - return _map_; \ - } \ - \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ - { \ - if (capacity == 0 || load <= 0) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_key || !f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry *[2])); \ - \ - if (!_map_->buffer) \ - { \ - alloc->free(_map_); \ - return NULL; \ - } \ - \ - _map_->count = 0; \ - _map_->capacity = real_capacity; \ - _map_->load = load; \ - _map_->flag = cmc_flags.OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->alloc = alloc; \ - _map_->callbacks = callbacks; \ - \ - return _map_; \ - } \ - \ - void PFX##_clear(struct SNAME *_map_) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct SNAME##_entry *scan = _map_->buffer[i][0]; \ - \ - while (scan != NULL) \ - { \ - struct SNAME##_entry *next = scan->next; \ - \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ - \ - _map_->alloc->free(scan); \ - \ - scan = next; \ - } \ - } \ - \ - memset(_map_->buffer, 0, \ - sizeof(struct SNAME##_entry *[2]) * _map_->capacity); \ - \ - _map_->count = 0; \ - _map_->flag = cmc_flags.OK; \ - } \ - \ - void PFX##_free(struct SNAME *_map_) \ - { \ - size_t index = 0; \ - \ - while (index < _map_->capacity) \ - { \ - struct SNAME##_entry *scan = _map_->buffer[index][0]; \ - \ - if (scan != NULL) \ - { \ - if (scan->next == NULL && scan->prev == NULL) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ - \ - _map_->alloc->free(scan); \ - } \ - else \ - { \ - while (scan != NULL) \ - { \ - struct SNAME##_entry *tmp = scan; \ - \ - scan = scan->next; \ - \ - if (_map_->f_key->free) \ - _map_->f_key->free(tmp->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(tmp->value); \ - \ - _map_->alloc->free(tmp); \ - } \ - } \ - } \ - \ - index++; \ - } \ - \ - _map_->alloc->free(_map_->buffer); \ - _map_->alloc->free(_map_); \ - } \ - \ - void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ - { \ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ - \ - _map_->callbacks = callbacks; \ - \ - _map_->flag = cmc_flags.OK; \ - } \ - \ - bool PFX##_insert(struct SNAME *_map_, K key, V value) \ - { \ - if (PFX##_full(_map_)) \ - { \ - if (!PFX##_resize(_map_, _map_->capacity + 1)) \ - return false; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - size_t pos = hash % _map_->capacity; \ - \ - struct SNAME##_entry *entry = PFX##_impl_new_entry(_map_, key, value); \ - \ - if (_map_->buffer[pos][0] == NULL) \ - { \ - _map_->buffer[pos][0] = entry; \ - _map_->buffer[pos][1] = entry; \ - } \ - else \ - { \ - entry->prev = _map_->buffer[pos][1]; \ - \ - _map_->buffer[pos][1]->next = entry; \ - _map_->buffer[pos][1] = entry; \ - } \ - \ - _map_->count++; \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return false; \ - } \ - \ - if (old_value) \ - *old_value = entry->value; \ - \ - entry->value = new_value; \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return true; \ - } \ - \ - size_t PFX##_update_all(struct SNAME *_map_, K key, V new_value, \ - V **old_values) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return 0; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct SNAME##_entry *entry = \ - _map_->buffer[hash % _map_->capacity][0]; \ - \ - if (entry == NULL) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return 0; \ - } \ - \ - if (old_values) \ - { \ - size_t total = PFX##_impl_key_count(_map_, key); \ - \ - if (total == 0) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return 0; \ - } \ - \ - *old_values = _map_->alloc->malloc(sizeof(V) * total); \ - \ - if (!(*old_values)) \ - { \ - _map_->flag = cmc_flags.ALLOC; \ - return 0; \ - } \ - } \ - \ - size_t index = 0; \ - \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (old_values) \ - (*old_values)[index] = entry->value; \ - \ - index++; \ - entry->value = new_value; \ - } \ - \ - entry = entry->next; \ - } \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return index; \ - } \ - \ - bool PFX##_remove(struct SNAME *_map_, K key, V *out_value) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct SNAME##_entry **head = \ - &(_map_->buffer[hash % _map_->capacity][0]); \ - struct SNAME##_entry **tail = \ - &(_map_->buffer[hash % _map_->capacity][1]); \ - \ - if (*head == NULL) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return false; \ - } \ - \ - struct SNAME##_entry *entry = *head; \ - \ - if (entry->next == NULL && entry->prev == NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - *head = NULL; \ - *tail = NULL; \ - \ - if (out_value) \ - *out_value = entry->value; \ - } \ - else \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return false; \ - } \ - } \ - else \ - { \ - bool found = false; \ - \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (*head == entry) \ - *head = entry->next; \ - if (*tail == entry) \ - *tail = entry->prev; \ - \ - if (entry->prev != NULL) \ - entry->prev->next = entry->next; \ - if (entry->next != NULL) \ - entry->next->prev = entry->prev; \ - \ - if (out_value) \ - *out_value = entry->value; \ - \ - found = true; \ - \ - break; \ - } \ - else \ - entry = entry->next; \ - } \ - \ - if (!found) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return false; \ - } \ - } \ - \ - _map_->alloc->free(entry); \ - \ - _map_->count--; \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - size_t PFX##_remove_all(struct SNAME *_map_, K key, V **out_values) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct SNAME##_entry **head = \ - &(_map_->buffer[hash % _map_->capacity][0]); \ - struct SNAME##_entry **tail = \ - &(_map_->buffer[hash % _map_->capacity][1]); \ - \ - if (*head == NULL) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return 0; \ - } \ - \ - if (out_values) \ - { \ - size_t total = PFX##_impl_key_count(_map_, key); \ - \ - if (total == 0) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return 0; \ - } \ - \ - *out_values = _map_->alloc->malloc(sizeof(V) * total); \ - \ - if (!(*out_values)) \ - { \ - _map_->flag = cmc_flags.ALLOC; \ - return 0; \ - } \ - } \ - \ - size_t index = 0; \ - struct SNAME##_entry *entry = *head; \ - \ - if (entry->next == NULL) \ - { \ - *head = NULL; \ - *tail = NULL; \ - \ - if (out_values) \ - (*out_values)[index] = entry->value; \ - \ - index++; \ - _map_->alloc->free(entry); \ - } \ - else \ - { \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (*head == entry) \ - *head = entry->next; \ - if (*tail == entry) \ - *tail = entry->prev; \ - \ - struct SNAME##_entry *next = entry->next; \ - \ - if (entry->prev != NULL) \ - entry->prev->next = entry->next; \ - if (entry->next != NULL) \ - entry->next->prev = entry->prev; \ - \ - if (out_values) \ - (*out_values)[index] = entry->value; \ - \ - index++; \ - _map_->alloc->free(entry); \ - \ - entry = next; \ - } \ - else \ - entry = entry->next; \ - } \ - } \ - \ - _map_->count -= index; \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return index; \ - } \ - \ - bool PFX##_max(struct SNAME *_map_, K *key, V *value) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - K max_key; \ - V max_val; \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map_); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - K result_key = PFX##_iter_key(&iter); \ - V result_value = PFX##_iter_value(&iter); \ - size_t index = PFX##_iter_index(&iter); \ - \ - if (index == 0) \ - { \ - max_key = result_key; \ - max_val = result_value; \ - } \ - else if (_map_->f_key->cmp(result_key, max_key) > 0) \ - { \ - max_key = result_key; \ - max_val = result_value; \ - } \ - } \ - \ - if (key) \ - *key = max_key; \ - if (value) \ - *value = max_val; \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool PFX##_min(struct SNAME *_map_, K *key, V *value) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - K min_key; \ - V min_val; \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map_); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - K result_key = PFX##_iter_key(&iter); \ - V result_value = PFX##_iter_value(&iter); \ - size_t index = PFX##_iter_index(&iter); \ - \ - if (index == 0) \ - { \ - min_key = result_key; \ - min_val = result_value; \ - } \ - else if (_map_->f_key->cmp(result_key, min_key) < 0) \ - { \ - min_key = result_key; \ - min_val = result_value; \ - } \ - } \ - \ - if (key) \ - *key = min_key; \ - if (value) \ - *value = min_val; \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - V PFX##_get(struct SNAME *_map_, K key) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return (V){ 0 }; \ - } \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return entry->value; \ - } \ - \ - V *PFX##_get_ref(struct SNAME *_map_, K key) \ - { \ - if (PFX##_empty(_map_)) \ - { \ - _map_->flag = cmc_flags.EMPTY; \ - return false; \ - } \ - \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = cmc_flags.NOT_FOUND; \ - return NULL; \ - } \ - \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return &(entry->value); \ - } \ - \ - bool PFX##_contains(struct SNAME *_map_, K key) \ - { \ - _map_->flag = cmc_flags.OK; \ - \ - bool result = PFX##_impl_get_entry(_map_, key) != NULL; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool PFX##_empty(struct SNAME *_map_) \ - { \ - return _map_->count == 0; \ - } \ - \ - bool PFX##_full(struct SNAME *_map_) \ - { \ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ - } \ - \ - size_t PFX##_count(struct SNAME *_map_) \ - { \ - return _map_->count; \ - } \ - \ - size_t PFX##_key_count(struct SNAME *_map_, K key) \ - { \ - return PFX##_impl_key_count(_map_, key); \ - } \ - \ - size_t PFX##_capacity(struct SNAME *_map_) \ - { \ - return _map_->capacity; \ - } \ - \ - double PFX##_load(struct SNAME *_map_) \ - { \ - return _map_->load; \ - } \ - \ - int PFX##_flag(struct SNAME *_map_) \ - { \ - return _map_->flag; \ - } \ - \ - bool PFX##_resize(struct SNAME *_map_, size_t capacity) \ - { \ - _map_->flag = cmc_flags.OK; \ - \ - if (_map_->capacity == capacity) \ - goto success; \ - \ - if (_map_->capacity > capacity / _map_->load) \ - goto success; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _map_->load) \ - { \ - _map_->flag = cmc_flags.ERROR; \ - return false; \ - } \ - \ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = PFX##_impl_calculate_size(capacity); \ - \ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _map_->count / _map_->load) \ - { \ - _map_->flag = cmc_flags.INVALID; \ - return false; \ - } \ - \ - /* No callbacks since _new_map_ is just a temporary hashtable */ \ - struct SNAME *_new_map_ = \ - PFX##_new_custom(capacity, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ - \ - if (!_new_map_) \ - { \ - _map_->flag = cmc_flags.ALLOC; \ - return false; \ - } \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map_); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - K key = PFX##_iter_key(&iter); \ - V value = PFX##_iter_value(&iter); \ - \ - /* TODO check for errors */ \ - PFX##_insert(_new_map_, key, value); \ - } \ - \ - if (_map_->count != _new_map_->count) \ - { \ - PFX##_free(_new_map_); \ - \ - _map_->flag = cmc_flags.ERROR; \ - return false; \ - } \ - \ - struct SNAME##_entry *(*tmp_b)[2] = _map_->buffer; \ - _map_->buffer = _new_map_->buffer; \ - _new_map_->buffer = tmp_b; \ - \ - size_t tmp_c = _map_->capacity; \ - _map_->capacity = _new_map_->capacity; \ - _new_map_->capacity = tmp_c; \ - \ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \ - _new_map_->f_val = &(struct SNAME##_fval){ NULL }; \ - \ - PFX##_free(_new_map_); \ - \ - success: \ - \ - if (_map_->callbacks && _map_->callbacks->resize) \ - _map_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_) \ - { \ - /* Callback will be added later */ \ - struct SNAME *result = \ - PFX##_new_custom(_map_->capacity * _map_->load, _map_->load, \ - _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ - \ - if (!result) \ - { \ - _map_->flag = cmc_flags.ERROR; \ - return NULL; \ - } \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map_); \ - \ - if (!PFX##_empty(_map_)) \ - { \ - /* TODO Turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - K key = PFX##_iter_key(&iter); \ - V value = PFX##_iter_value(&iter); \ - \ - if (_map_->f_key->cpy) \ - key = _map_->f_key->cpy(key); \ - if (_map_->f_val->cpy) \ - value = _map_->f_val->cpy(value); \ - \ - /* TODO check for errors */ \ - PFX##_insert(result, key, value); \ - } \ - } \ - \ - result->callbacks = _map_->callbacks; \ - _map_->flag = cmc_flags.OK; \ - \ - return result; \ - } \ - \ - bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \ - { \ - _map1_->flag = cmc_flags.OK; \ - _map2_->flag = cmc_flags.OK; \ - \ - if (_map1_->count != _map2_->count) \ - return false; \ - \ - struct SNAME##_iter iter = PFX##_iter_start(_map1_); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ - { \ - K key = PFX##_iter_key(&iter); \ - \ - if (PFX##_impl_key_count(_map1_, key) != \ - PFX##_impl_key_count(_map2_, key)) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string PFX##_to_string(struct SNAME *_map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmultimap, \ - #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \ - m_->alloc, m_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool PFX##_print(struct SNAME *_map_, FILE *fptr) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct SNAME##_entry *scan = _map_->buffer[i][0]; \ - \ - while (scan != NULL) \ - { \ - if (!_map_->f_key->str(fptr, scan->key) || \ - !_map_->f_val->str(fptr, scan->value)) \ - return false; \ - \ - scan = scan->next; \ - } \ - } \ - \ - return true; \ - } \ - \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ - { \ - struct SNAME##_iter iter; \ - \ - iter.target = target; \ - iter.curr_entry = NULL; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = PFX##_empty(target); \ - \ - if (!PFX##_empty(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i][0] != NULL) \ - { \ - iter.curr_entry = target->buffer[i][0]; \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1][1] != NULL) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ - { \ - struct SNAME##_iter iter; \ - \ - iter.target = target; \ - iter.curr_entry = NULL; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = PFX##_empty(target); \ - iter.end = true; \ - \ - if (!PFX##_empty(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i][0] != NULL) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1][1] != NULL) \ - { \ - iter.curr_entry = target->buffer[i - 1][1]; \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->start; \ - } \ - \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->end; \ - } \ - \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ - { \ - if (!PFX##_empty(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ - iter->curr_entry = iter->target->buffer[iter->first][0]; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ - { \ - if (!PFX##_empty(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ - iter->end = true; \ - iter->curr_entry = iter->target->buffer[iter->last][1]; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->curr_entry->next != NULL) \ - { \ - iter->curr_entry = iter->curr_entry->next; \ - iter->index++; \ - } \ - else \ - { \ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->cursor++; \ - \ - while (iter->target->buffer[iter->cursor][0] == NULL) \ - iter->cursor++; \ - \ - iter->curr_entry = iter->target->buffer[iter->cursor][0]; \ - \ - iter->index++; \ - } \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - return true; \ - } \ - \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->curr_entry->prev != NULL) \ - { \ - iter->curr_entry = iter->curr_entry->prev; \ - iter->index--; \ - } \ - else \ - { \ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->cursor--; \ - \ - while (iter->target->buffer[iter->cursor][1] == NULL) \ - iter->cursor--; \ - \ - iter->curr_entry = iter->target->buffer[iter->cursor][1]; \ - \ - iter->index--; \ - } \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - PFX##_iter_next(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - PFX##_iter_prev(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ - else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - K PFX##_iter_key(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return (K){ 0 }; \ - \ - return iter->curr_entry->key; \ - } \ - \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->curr_entry->value; \ - } \ - \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return NULL; \ - \ - return &(iter->curr_entry->value); \ - } \ - \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ - { \ - return iter->index; \ - } \ - \ - struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, K key, \ - V value) \ - { \ - struct SNAME##_entry *entry = \ - _map_->alloc->malloc(sizeof(struct SNAME##_entry)); \ - \ - if (!entry) \ - return NULL; \ - \ - entry->key = key; \ - entry->value = value; \ - entry->next = NULL; \ - entry->prev = NULL; \ - \ - return entry; \ - } \ - \ - struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct SNAME##_entry *entry = \ - _map_->buffer[hash % _map_->capacity][0]; \ - \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - return entry; \ - \ - entry = entry->next; \ - } \ - \ - return NULL; \ - } \ - \ - size_t PFX##_impl_key_count(struct SNAME *_map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct SNAME##_entry *entry = \ - _map_->buffer[hash % _map_->capacity][0]; \ - \ - size_t total_count = 0; \ - \ - if (!entry) \ - return total_count; \ - \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - total_count++; \ - \ - entry = entry->next; \ - } \ - \ - return total_count; \ - } \ - \ - size_t PFX##_impl_calculate_size(size_t required) \ - { \ - const size_t count = \ - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ - \ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ - \ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ - \ - return cmc_hashtable_primes[i]; \ +#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ + \ + /* Implementation Detail Functions */ \ + struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \ + struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \ + size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key); \ + size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ + \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ + \ + if (capacity == 0 || load <= 0) \ + return NULL; \ + \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ + \ + if (!f_key || !f_val) \ + return NULL; \ + \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ + \ + struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_map_) \ + return NULL; \ + \ + _map_->buffer = alloc->calloc( \ + real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ + \ + if (!_map_->buffer) \ + { \ + alloc->free(_map_); \ + return NULL; \ + } \ + \ + _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 = NULL; \ + \ + return _map_; \ + } \ + \ + struct SNAME *CMC_(PFX, _new_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) \ + { \ + if (capacity == 0 || load <= 0) \ + return NULL; \ + \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ + \ + if (!f_key || !f_val) \ + return NULL; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ + \ + struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_map_) \ + return NULL; \ + \ + _map_->buffer = alloc->calloc( \ + real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ + \ + if (!_map_->buffer) \ + { \ + alloc->free(_map_); \ + return NULL; \ + } \ + \ + _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_; \ + } \ + \ + void CMC_(PFX, _clear)(struct SNAME * _map_) \ + { \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ + \ + while (scan != NULL) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *next = scan->next; \ + \ + if (_map_->f_key->free) \ + _map_->f_key->free(scan->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(scan->value); \ + \ + _map_->alloc->free(scan); \ + \ + scan = next; \ + } \ + } \ + \ + memset(_map_->buffer, 0, \ + sizeof(struct CMC_DEF_ENTRY(SNAME) *[2]) * _map_->capacity); \ + \ + _map_->count = 0; \ + _map_->flag = CMC_FLAG_OK; \ + } \ + \ + void CMC_(PFX, _free)(struct SNAME * _map_) \ + { \ + size_t index = 0; \ + \ + while (index < _map_->capacity) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[index][0]; \ + \ + if (scan != NULL) \ + { \ + if (scan->next == NULL && scan->prev == NULL) \ + { \ + if (_map_->f_key->free) \ + _map_->f_key->free(scan->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(scan->value); \ + \ + _map_->alloc->free(scan); \ + } \ + else \ + { \ + while (scan != NULL) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *tmp = scan; \ + \ + scan = scan->next; \ + \ + if (_map_->f_key->free) \ + _map_->f_key->free(tmp->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(tmp->value); \ + \ + _map_->alloc->free(tmp); \ + } \ + } \ + } \ + \ + index++; \ + } \ + \ + _map_->alloc->free(_map_->buffer); \ + _map_->alloc->free(_map_); \ + } \ + \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + if (!alloc) \ + _map_->alloc = &cmc_alloc_node_default; \ + else \ + _map_->alloc = alloc; \ + \ + _map_->callbacks = callbacks; \ + \ + _map_->flag = CMC_FLAG_OK; \ + } \ + \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ + { \ + if (CMC_(PFX, _full)(_map_)) \ + { \ + if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ + return false; \ + } \ + \ + size_t hash = _map_->f_key->hash(key); \ + size_t pos = hash % _map_->capacity; \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_new_entry)(_map_, key, value); \ + \ + if (_map_->buffer[pos][0] == NULL) \ + { \ + _map_->buffer[pos][0] = entry; \ + _map_->buffer[pos][1] = entry; \ + } \ + else \ + { \ + entry->prev = _map_->buffer[pos][1]; \ + \ + _map_->buffer[pos][1]->next = entry; \ + _map_->buffer[pos][1] = entry; \ + } \ + \ + _map_->count++; \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->create) \ + _map_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ + V * old_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_map_, key); \ + \ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ + \ + if (old_value) \ + *old_value = entry->value; \ + \ + entry->value = new_value; \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ + \ + return true; \ + } \ + \ + size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, \ + V * *old_values) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return 0; \ + } \ + \ + size_t hash = _map_->f_key->hash(key); \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + _map_->buffer[hash % _map_->capacity][0]; \ + \ + if (entry == NULL) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ + \ + if (old_values) \ + { \ + size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \ + \ + if (total == 0) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ + \ + *old_values = _map_->alloc->malloc(sizeof(V) * total); \ + \ + if (!(*old_values)) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return 0; \ + } \ + } \ + \ + size_t index = 0; \ + \ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + { \ + if (old_values) \ + (*old_values)[index] = entry->value; \ + \ + index++; \ + entry->value = new_value; \ + } \ + \ + entry = entry->next; \ + } \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ + \ + return index; \ + } \ + \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + size_t hash = _map_->f_key->hash(key); \ + \ + struct CMC_DEF_ENTRY(SNAME) **head = \ + &(_map_->buffer[hash % _map_->capacity][0]); \ + struct CMC_DEF_ENTRY(SNAME) **tail = \ + &(_map_->buffer[hash % _map_->capacity][1]); \ + \ + if (*head == NULL) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = *head; \ + \ + if (entry->next == NULL && entry->prev == NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + { \ + *head = NULL; \ + *tail = NULL; \ + \ + if (out_value) \ + *out_value = entry->value; \ + } \ + else \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ + } \ + else \ + { \ + bool found = false; \ + \ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + { \ + if (*head == entry) \ + *head = entry->next; \ + if (*tail == entry) \ + *tail = entry->prev; \ + \ + if (entry->prev != NULL) \ + entry->prev->next = entry->next; \ + if (entry->next != NULL) \ + entry->next->prev = entry->prev; \ + \ + if (out_value) \ + *out_value = entry->value; \ + \ + found = true; \ + \ + break; \ + } \ + else \ + entry = entry->next; \ + } \ + \ + if (!found) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ + } \ + \ + _map_->alloc->free(entry); \ + \ + _map_->count--; \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, \ + V * *out_values) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + size_t hash = _map_->f_key->hash(key); \ + \ + struct CMC_DEF_ENTRY(SNAME) **head = \ + &(_map_->buffer[hash % _map_->capacity][0]); \ + struct CMC_DEF_ENTRY(SNAME) **tail = \ + &(_map_->buffer[hash % _map_->capacity][1]); \ + \ + if (*head == NULL) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ + \ + if (out_values) \ + { \ + size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \ + \ + if (total == 0) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ + \ + *out_values = _map_->alloc->malloc(sizeof(V) * total); \ + \ + if (!(*out_values)) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return 0; \ + } \ + } \ + \ + size_t index = 0; \ + struct CMC_DEF_ENTRY(SNAME) *entry = *head; \ + \ + if (entry->next == NULL) \ + { \ + *head = NULL; \ + *tail = NULL; \ + \ + if (out_values) \ + (*out_values)[index] = entry->value; \ + \ + index++; \ + _map_->alloc->free(entry); \ + } \ + else \ + { \ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + { \ + if (*head == entry) \ + *head = entry->next; \ + if (*tail == entry) \ + *tail = entry->prev; \ + \ + struct CMC_DEF_ENTRY(SNAME) *next = entry->next; \ + \ + if (entry->prev != NULL) \ + entry->prev->next = entry->next; \ + if (entry->next != NULL) \ + entry->next->prev = entry->prev; \ + \ + if (out_values) \ + (*out_values)[index] = entry->value; \ + \ + index++; \ + _map_->alloc->free(entry); \ + \ + entry = next; \ + } \ + else \ + entry = entry->next; \ + } \ + } \ + \ + _map_->count -= index; \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ + \ + return index; \ + } \ + \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + K max_key; \ + V max_val; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + \ + /* TODO Turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K result_key = CMC_(PFX, _iter_key)(&iter); \ + V result_value = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ + \ + if (index == 0) \ + { \ + max_key = result_key; \ + max_val = result_value; \ + } \ + else if (_map_->f_key->cmp(result_key, max_key) > 0) \ + { \ + max_key = result_key; \ + max_val = result_value; \ + } \ + } \ + \ + if (key) \ + *key = max_key; \ + if (value) \ + *value = max_val; \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + K min_key; \ + V min_val; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + \ + /* TODO Turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K result_key = CMC_(PFX, _iter_key)(&iter); \ + V result_value = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ + \ + if (index == 0) \ + { \ + min_key = result_key; \ + min_val = result_value; \ + } \ + else if (_map_->f_key->cmp(result_key, min_key) < 0) \ + { \ + min_key = result_key; \ + min_val = result_value; \ + } \ + } \ + \ + if (key) \ + *key = min_key; \ + if (value) \ + *value = min_val; \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_map_, key); \ + \ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return (V){ 0 }; \ + } \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return entry->value; \ + } \ + \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_map_, key); \ + \ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return NULL; \ + } \ + \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return &(entry->value); \ + } \ + \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ + { \ + _map_->flag = CMC_FLAG_OK; \ + \ + bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ + \ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _empty)(struct SNAME * _map_) \ + { \ + return _map_->count == 0; \ + } \ + \ + bool CMC_(PFX, _full)(struct SNAME * _map_) \ + { \ + return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ + } \ + \ + size_t CMC_(PFX, _count)(struct SNAME * _map_) \ + { \ + return _map_->count; \ + } \ + \ + size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key) \ + { \ + return CMC_(PFX, _impl_key_count)(_map_, key); \ + } \ + \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ + { \ + return _map_->capacity; \ + } \ + \ + double CMC_(PFX, _load)(struct SNAME * _map_) \ + { \ + return _map_->load; \ + } \ + \ + int CMC_(PFX, _flag)(struct SNAME * _map_) \ + { \ + return _map_->flag; \ + } \ + \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ + { \ + _map_->flag = CMC_FLAG_OK; \ + \ + if (_map_->capacity == capacity) \ + goto success; \ + \ + if (_map_->capacity > capacity / _map_->load) \ + goto success; \ + \ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * _map_->load) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ + \ + /* Calculate required capacity based on the prime numbers */ \ + size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ + \ + /* Not possible to shrink with current available prime numbers */ \ + if (theoretical_size < _map_->count / _map_->load) \ + { \ + _map_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + /* No callbacks since _new_map_ is just a temporary hashtable */ \ + struct SNAME *_new_map_ = \ + CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, NULL); \ + \ + if (!_new_map_) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + \ + /* TODO Turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K key = CMC_(PFX, _iter_key)(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + /* TODO check for errors */ \ + CMC_(PFX, _insert)(_new_map_, key, value); \ + } \ + \ + if (_map_->count != _new_map_->count) \ + { \ + CMC_(PFX, _free)(_new_map_); \ + \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) * (*tmp_b)[2] = _map_->buffer; \ + _map_->buffer = _new_map_->buffer; \ + _new_map_->buffer = tmp_b; \ + \ + size_t tmp_c = _map_->capacity; \ + _map_->capacity = _new_map_->capacity; \ + _new_map_->capacity = tmp_c; \ + \ + /* Prevent the map from freeing the data */ \ + _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ + _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ + \ + CMC_(PFX, _free)(_new_map_); \ + \ + success: \ + \ + if (_map_->callbacks && _map_->callbacks->resize) \ + _map_->callbacks->resize(); \ + \ + return true; \ + } \ + \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ + { \ + /* Callback will be added later */ \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _map_->capacity * _map_->load, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, NULL); \ + \ + if (!result) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + \ + if (!CMC_(PFX, _empty)(_map_)) \ + { \ + /* TODO Turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); \ + CMC_(PFX, _iter_next)(&iter)) \ + { \ + K key = CMC_(PFX, _iter_key)(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (_map_->f_key->cpy) \ + key = _map_->f_key->cpy(key); \ + if (_map_->f_val->cpy) \ + value = _map_->f_val->cpy(value); \ + \ + /* TODO check for errors */ \ + CMC_(PFX, _insert)(result, key, value); \ + } \ + } \ + \ + result->callbacks = _map_->callbacks; \ + _map_->flag = CMC_FLAG_OK; \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ + { \ + _map1_->flag = CMC_FLAG_OK; \ + _map2_->flag = CMC_FLAG_OK; \ + \ + if (_map1_->count != _map2_->count) \ + return false; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ + \ + /* TODO Turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K key = CMC_(PFX, _iter_key)(&iter); \ + \ + if (CMC_(PFX, _impl_key_count)(_map1_, key) != \ + CMC_(PFX, _impl_key_count)(_map2_, key)) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ + { \ + struct cmc_string str; \ + struct SNAME *m_ = _map_; \ + \ + int n = snprintf( \ + str.s, cmc_string_len, cmc_cmc_string_fmt_hashmultimap, #SNAME, \ + #K, #V, m_, m_->buffer, m_->capacity, m_->count, m_->load, \ + m_->flag, m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ + \ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ + { \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ + \ + while (scan != NULL) \ + { \ + if (!_map_->f_key->str(fptr, scan->key) || \ + !_map_->f_val->str(fptr, scan->value)) \ + return false; \ + \ + scan = scan->next; \ + } \ + } \ + \ + return true; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.curr_entry = NULL; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i][0] != NULL) \ + { \ + iter.curr_entry = target->buffer[i][0]; \ + iter.first = i; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.first; \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1][1] != NULL) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.curr_entry = NULL; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i][0] != NULL) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1][1] != NULL) \ + { \ + iter.curr_entry = target->buffer[i - 1][1]; \ + iter.last = i - 1; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + iter->curr_entry = iter->target->buffer[iter->first][0]; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + iter->curr_entry = iter->target->buffer[iter->last][1]; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->curr_entry->next != NULL) \ + { \ + iter->curr_entry = iter->curr_entry->next; \ + iter->index++; \ + } \ + else \ + { \ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->cursor++; \ + \ + while (iter->target->buffer[iter->cursor][0] == NULL) \ + iter->cursor++; \ + \ + iter->curr_entry = iter->target->buffer[iter->cursor][0]; \ + \ + iter->index++; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->curr_entry->prev != NULL) \ + { \ + iter->curr_entry = iter->curr_entry->prev; \ + iter->index--; \ + } \ + else \ + { \ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->cursor--; \ + \ + while (iter->target->buffer[iter->cursor][1] == NULL) \ + iter->cursor--; \ + \ + iter->curr_entry = iter->target->buffer[iter->cursor][1]; \ + \ + iter->index--; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (K){ 0 }; \ + \ + return iter->curr_entry->key; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->curr_entry->value; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->curr_entry->value); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \ + \ + if (!entry) \ + return NULL; \ + \ + entry->key = key; \ + entry->value = value; \ + entry->next = NULL; \ + entry->prev = NULL; \ + \ + return entry; \ + } \ + \ + struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ + { \ + size_t hash = _map_->f_key->hash(key); \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + _map_->buffer[hash % _map_->capacity][0]; \ + \ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + return entry; \ + \ + entry = entry->next; \ + } \ + \ + return NULL; \ + } \ + \ + size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key) \ + { \ + size_t hash = _map_->f_key->hash(key); \ + \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + _map_->buffer[hash % _map_->capacity][0]; \ + \ + size_t total_count = 0; \ + \ + if (!entry) \ + return total_count; \ + \ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + total_count++; \ + \ + entry = entry->next; \ + } \ + \ + return total_count; \ + } \ + \ + size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ + { \ + const size_t count = \ + sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ + \ + if (cmc_hashtable_primes[count - 1] < required) \ + return required; \ + \ + size_t i = 0; \ + while (cmc_hashtable_primes[i] < required) \ + i++; \ + \ + return cmc_hashtable_primes[i]; \ } -#endif /* CMC_HASHMULTIMAP_H */ +#endif /* CMC_CMC_HASHMULTIMAP_H */ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index 9a92106..b2c5613 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -23,8 +23,8 @@ * mapped to their multiplicity. */ -#ifndef CMC_HASHMULTISET_H -#define CMC_HASHMULTISET_H +#ifndef CMC_CMC_HASHMULTISET_H +#define CMC_CMC_HASHMULTISET_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -40,38 +40,44 @@ * HashMultiSet specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "cardinality:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_hashmultiset = + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "cardinality:%" PRIuMAX ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_HASHMULTISET(PFX, SNAME, V) \ - CMC_GENERATE_HASHMULTISET_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_HASHMULTISET_SOURCE(PFX, SNAME, V) +/** + * Core HashMultiSet implementation + */ +#define CMC_CMC_HASHMULTISET_CORE(BODY) \ + CMC_CMC_HASHMULTISET_CORE_HEADER(BODY) \ + CMC_CMC_HASHMULTISET_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_HASHMULTISET_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMULTISET_HEADER(PFX, SNAME, V) +#define CMC_CMC_HASHMULTISET_CORE_HEADER(BODY) \ + CMC_CMC_HASHMULTISET_CORE_HEADER_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_HASHMULTISET_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHMULTISET_SOURCE(PFX, SNAME, V) +#define CMC_CMC_HASHMULTISET_CORE_SOURCE(BODY) \ + CMC_CMC_HASHMULTISET_CORE_SOURCE_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHMULTISET_HEADER(PFX, SNAME, V) \ +#define CMC_CMC_HASHMULTISET_CORE_HEADER_(PFX, SNAME, V) \ \ /* HashMultiset Structure */ \ struct SNAME \ { \ /* Array of Entries */ \ - struct SNAME##_entry *buffer; \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ \ /* Current Array Capcity */ \ size_t capacity; \ @@ -89,7 +95,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " int flag; \ \ /* Key function table */ \ - struct SNAME##_fval *f_val; \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ \ /* Custom allocation functions */ \ struct cmc_alloc_node *alloc; \ @@ -98,7 +104,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " struct cmc_callbacks *callbacks; \ }; \ \ - struct SNAME##_entry \ + struct CMC_DEF_ENTRY(SNAME) \ { \ /* Entry element */ \ V value; \ @@ -115,7 +121,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " }; \ \ /* Value struct function table */ \ - struct SNAME##_fval \ + struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ int (*cmp)(V, V); \ @@ -137,7 +143,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " }; \ \ /* HashMultiset Iterator */ \ - struct SNAME##_iter \ + struct CMC_DEF_ITER(SNAME) \ { \ /* Target HashMultiset */ \ struct SNAME *target; \ @@ -163,92 +169,105 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_set_); \ - void PFX##_free(struct SNAME *_set_); \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _set_); \ + void CMC_(PFX, _free)(struct SNAME * _set_); \ /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ + void CMC_(PFX, _customize)(struct SNAME * _set_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_set_, V value); \ - bool PFX##_insert_many(struct SNAME *_set_, V value, size_t count); \ - bool PFX##_update(struct SNAME *_set_, V value, size_t multiplicity); \ - bool PFX##_remove(struct SNAME *_set_, V value); \ - size_t PFX##_remove_all(struct SNAME *_set_, V value); \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count); \ + bool CMC_(PFX, _update)(struct SNAME * _set_, V value, \ + size_t multiplicity); \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ + size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value); \ /* Element Access */ \ - bool PFX##_max(struct SNAME *_set_, V *value); \ - bool PFX##_min(struct SNAME *_set_, V *value); \ - size_t PFX##_multiplicity_of(struct SNAME *_set_, V value); \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ + size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value); \ /* Collection State */ \ - bool PFX##_contains(struct SNAME *_set_, V value); \ - bool PFX##_empty(struct SNAME *_set_); \ - bool PFX##_full(struct SNAME *_set_); \ - size_t PFX##_count(struct SNAME *_set_); \ - size_t PFX##_cardinality(struct SNAME *_set_); \ - size_t PFX##_capacity(struct SNAME *_set_); \ - double PFX##_load(struct SNAME *_set_); \ - int PFX##_flag(struct SNAME *_set_); \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _set_); \ + bool CMC_(PFX, _full)(struct SNAME * _set_); \ + size_t CMC_(PFX, _count)(struct SNAME * _set_); \ + size_t CMC_(PFX, _cardinality)(struct SNAME * _set_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ + double CMC_(PFX, _load)(struct SNAME * _set_); \ + int CMC_(PFX, _flag)(struct SNAME * _set_); \ /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_set_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_); \ - bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_set_); \ - bool PFX##_print(struct SNAME *_set_, FILE *fptr); \ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \ \ /* Set Operations */ \ - struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \ - struct SNAME *PFX##_intersection(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - struct SNAME *PFX##_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - struct SNAME *PFX##_summation(struct SNAME *_set1_, struct SNAME *_set2_); \ - struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_); \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ \ /* Iterator Functions */ \ /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - size_t PFX##_iter_multiplicity(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHMULTISET_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_HASHMULTISET_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ - static size_t PFX##_impl_multiplicity_of(struct SNAME *_set_, V value); \ - static struct SNAME##_entry *PFX##_impl_insert_and_return( \ - struct SNAME *_set_, V value, bool *new_node); \ - static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \ - V value); \ - static size_t PFX##_impl_calculate_size(size_t required); \ + static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, \ + V value); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, \ + bool *new_node); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -262,7 +281,8 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " if (!f_val) \ return NULL; \ \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ \ struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ \ @@ -270,7 +290,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return NULL; \ \ _set_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \ + alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ \ if (!_set_->buffer) \ { \ @@ -282,7 +302,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " _set_->cardinality = 0; \ _set_->capacity = real_capacity; \ _set_->load = load; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ _set_->f_val = f_val; \ _set_->alloc = alloc; \ _set_->callbacks = NULL; \ @@ -290,9 +310,9 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return _set_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ @@ -304,7 +324,8 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " if (!f_val) \ return NULL; \ \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ \ if (!alloc) \ alloc = &cmc_alloc_node_default; \ @@ -315,7 +336,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return NULL; \ \ _set_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \ + alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ \ if (!_set_->buffer) \ { \ @@ -327,7 +348,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " _set_->cardinality = 0; \ _set_->capacity = real_capacity; \ _set_->load = load; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ _set_->f_val = f_val; \ _set_->alloc = alloc; \ _set_->callbacks = callbacks; \ @@ -335,13 +356,13 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return _set_; \ } \ \ - void PFX##_clear(struct SNAME *_set_) \ + void CMC_(PFX, _clear)(struct SNAME * _set_) \ { \ if (_set_->f_val->free) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ - struct SNAME##_entry *entry = &(_set_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ \ if (entry->state == CMC_ES_FILLED) \ { \ @@ -351,19 +372,19 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " } \ \ memset(_set_->buffer, 0, \ - sizeof(struct SNAME##_entry) * _set_->capacity); \ + sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ \ _set_->count = 0; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_set_) \ + void CMC_(PFX, _free)(struct SNAME * _set_) \ { \ if (_set_->f_val->free) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ - struct SNAME##_entry *entry = &(_set_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ \ if (entry->state == CMC_ES_FILLED) \ { \ @@ -376,8 +397,9 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " _set_->alloc->free(_set_); \ } \ \ - void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _set_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ @@ -386,19 +408,19 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " \ _set_->callbacks = callbacks; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_insert(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ { \ bool new_node; \ \ - struct SNAME##_entry *entry = \ - PFX##_impl_insert_and_return(_set_, value, &new_node); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ \ if (!entry) \ { \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ @@ -406,7 +428,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " entry->multiplicity++; \ \ _set_->cardinality++; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->create) \ _set_->callbacks->create(); \ @@ -414,19 +436,19 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_insert_many(struct SNAME *_set_, V value, size_t count) \ + bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count) \ { \ if (count == 0) \ goto success; \ \ bool new_node; \ \ - struct SNAME##_entry *entry = \ - PFX##_impl_insert_and_return(_set_, value, &new_node); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ \ if (!entry) \ { \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ @@ -439,7 +461,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " \ success: \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->create) \ _set_->callbacks->create(); \ @@ -447,12 +469,14 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_update(struct SNAME *_set_, V value, size_t multiplicity) \ + bool CMC_(PFX, _update)(struct SNAME * _set_, V value, \ + size_t multiplicity) \ { \ if (multiplicity == 0) \ { \ /* Effectively delete the entry */ \ - struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, value); \ + struct CMC_DEF_ENTRY(SNAME) *result = \ + CMC_(PFX, _impl_get_entry)(_set_, value); \ \ if (!result) \ /* If no entry was found then its multiplicity is already 0 */ \ @@ -471,8 +495,8 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " \ bool new_node; \ \ - struct SNAME##_entry *entry = \ - PFX##_impl_insert_and_return(_set_, value, &new_node); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ \ if (!entry) \ return false; \ @@ -487,7 +511,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " \ success: \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->update) \ _set_->callbacks->update(); \ @@ -495,19 +519,20 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_remove(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, value); \ + struct CMC_DEF_ENTRY(SNAME) *result = \ + CMC_(PFX, _impl_get_entry)(_set_, value); \ \ if (!result) \ { \ - _set_->flag = cmc_flags.NOT_FOUND; \ + _set_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ @@ -524,7 +549,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " } \ \ _set_->cardinality--; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->delete) \ _set_->callbacks->delete (); \ @@ -532,19 +557,20 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - size_t PFX##_remove_all(struct SNAME *_set_, V value) \ + size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, value); \ + struct CMC_DEF_ENTRY(SNAME) *result = \ + CMC_(PFX, _impl_get_entry)(_set_, value); \ \ if (!result) \ { \ - _set_->flag = cmc_flags.NOT_FOUND; \ + _set_->flag = CMC_FLAG_NOT_FOUND; \ return 0; \ } \ \ @@ -557,7 +583,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " \ _set_->count--; \ _set_->cardinality -= removed; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->delete) \ _set_->callbacks->delete (); \ @@ -565,22 +591,22 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return removed; \ } \ \ - bool PFX##_max(struct SNAME *_set_, V *value) \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ V max_val; \ - struct SNAME##_iter iter = PFX##_iter_start(_set_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO transform this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V result = PFX##_iter_value(&iter); \ - size_t index = PFX##_iter_index(&iter); \ + V result = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ \ if (index == 0) \ max_val = result; \ @@ -591,7 +617,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " if (value) \ *value = max_val; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -599,22 +625,22 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_min(struct SNAME *_set_, V *value) \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ V min_val; \ - struct SNAME##_iter iter = PFX##_iter_start(_set_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO transform this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V result = PFX##_iter_value(&iter); \ - size_t index = PFX##_iter_index(&iter); \ + V result = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ \ if (index == 0) \ min_val = result; \ @@ -625,7 +651,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " if (value) \ *value = min_val; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -633,11 +659,12 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - size_t PFX##_multiplicity_of(struct SNAME *_set_, V value) \ + size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value) \ { \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_set_, value); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_set_, value); \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -648,11 +675,11 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return entry->multiplicity; \ } \ \ - bool PFX##_contains(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ { \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ - bool result = PFX##_impl_get_entry(_set_, value) != NULL; \ + bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -660,44 +687,44 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_set_) \ + bool CMC_(PFX, _empty)(struct SNAME * _set_) \ { \ return _set_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_set_) \ + bool CMC_(PFX, _full)(struct SNAME * _set_) \ { \ return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ } \ \ - size_t PFX##_count(struct SNAME *_set_) \ + size_t CMC_(PFX, _count)(struct SNAME * _set_) \ { \ return _set_->count; \ } \ \ - size_t PFX##_cardinality(struct SNAME *_set_) \ + size_t CMC_(PFX, _cardinality)(struct SNAME * _set_) \ { \ return _set_->cardinality; \ } \ \ - size_t PFX##_capacity(struct SNAME *_set_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \ { \ return _set_->capacity; \ } \ \ - double PFX##_load(struct SNAME *_set_) \ + double CMC_(PFX, _load)(struct SNAME * _set_) \ { \ return _set_->load; \ } \ \ - int PFX##_flag(struct SNAME *_set_) \ + int CMC_(PFX, _flag)(struct SNAME * _set_) \ { \ return _set_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_set_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \ { \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->capacity == capacity) \ goto success; \ @@ -708,48 +735,49 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " /* Prevent integer overflow */ \ if (capacity >= UINTMAX_MAX * _set_->load) \ { \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = PFX##_impl_calculate_size(capacity); \ + size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ \ /* Not possible to shrink with current available prime numbers */ \ if (theoretical_size < _set_->count / _set_->load) \ { \ - _set_->flag = cmc_flags.INVALID; \ + _set_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ /* No callbacks since _new_set_ is just a temporary hashtable */ \ - struct SNAME *_new_set_ = PFX##_new_custom( \ + struct SNAME *_new_set_ = CMC_(PFX, _new_custom)( \ capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \ \ if (!_new_set_) \ { \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO transform this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - PFX##_insert_many(_new_set_, PFX##_iter_value(&iter), \ - PFX##_iter_multiplicity(&iter)); \ + CMC_(PFX, _insert_many) \ + (_new_set_, CMC_(PFX, _iter_value)(&iter), \ + CMC_(PFX, _iter_multiplicity)(&iter)); \ } \ \ if (_set_->count != _new_set_->count) \ { \ - PFX##_free(_new_set_); \ + CMC_(PFX, _free)(_new_set_); \ \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ - struct SNAME##_entry *tmp_b = _set_->buffer; \ + struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \ _set_->buffer = _new_set_->buffer; \ _new_set_->buffer = tmp_b; \ \ @@ -758,9 +786,9 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " _new_set_->capacity = tmp_c; \ \ /* Prevent the set from freeing the data */ \ - _new_set_->f_val = &(struct SNAME##_fval){ NULL }; \ + _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ \ - PFX##_free(_new_set_); \ + CMC_(PFX, _free)(_new_set_); \ \ success: \ \ @@ -770,15 +798,15 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ { \ - struct SNAME *result = \ - PFX##_new_custom(_set_->capacity * _set_->load, _set_->load, \ - _set_->f_val, _set_->alloc, _set_->callbacks); \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _set_->capacity * _set_->load, _set_->load, _set_->f_val, \ + _set_->alloc, _set_->callbacks); \ \ if (!result) \ { \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ @@ -786,11 +814,12 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ - struct SNAME##_entry *scan = &(_set_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \ \ if (scan->state != CMC_ES_EMPTY) \ { \ - struct SNAME##_entry *target = &(result->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *target = \ + &(result->buffer[i]); \ \ if (scan->state == CMC_ES_DELETED) \ target->state = CMC_ES_DELETED; \ @@ -807,20 +836,20 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " } \ else \ memcpy(result->buffer, _set_->buffer, \ - sizeof(struct SNAME##_entry) * _set_->capacity); \ + sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ \ result->count = _set_->count; \ result->cardinality = _set_->cardinality; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ - _set1_->flag = cmc_flags.OK; \ - _set2_->flag = cmc_flags.OK; \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ \ if (_set1_->count != _set2_->count) \ return false; \ @@ -831,41 +860,41 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " if (_set1_->count == 0) \ return true; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - struct SNAME##_entry *entry = \ - PFX##_impl_get_entry(_set2_, PFX##_iter_value(&iter)); \ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)( \ + _set2_, CMC_(PFX, _iter_value)(&iter)); \ \ if (!entry) \ return false; \ \ - if (entry->multiplicity != PFX##_iter_multiplicity(&iter)) \ + if (entry->multiplicity != CMC_(PFX, _iter_multiplicity)(&iter)) \ return false; \ } \ \ return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_set_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \ { \ struct cmc_string str; \ struct SNAME *s_ = _set_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmultiset, \ - #SNAME, #V, s_, s_->buffer, s_->capacity, s_->count, \ - s_->cardinality, s_->load, s_->flag, s_->f_val, \ - s_->alloc, s_->callbacks); \ + int n = snprintf( \ + str.s, cmc_string_len, cmc_cmc_string_fmt_hashmultiset, #SNAME, \ + #V, s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, \ + s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_set_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ - struct SNAME##_entry *entry = &(_set_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ \ if (entry->state == CMC_ES_FILLED) \ { \ @@ -877,39 +906,42 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ return NULL; \ \ - struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \ - struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ \ - for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ { \ - V value = PFX##_iter_value(&iter1); \ + V value = CMC_(PFX, _iter_value)(&iter1); \ \ - size_t m1 = PFX##_iter_multiplicity(&iter1); \ - size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ size_t max_ = m1 > m2 ? m1 : m2; \ \ - PFX##_update(_set_r_, value, max_); \ + CMC_(PFX, _update)(_set_r_, value, max_); \ } \ \ - for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ { \ - V value = PFX##_iter_value(&iter2); \ + V value = CMC_(PFX, _iter_value)(&iter2); \ \ - size_t m1 = PFX##_impl_multiplicity_of(_set1_, value); \ - size_t m2 = PFX##_iter_multiplicity(&iter2); \ + size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ + size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ size_t max_ = m1 > m2 ? m1 : m2; \ \ - PFX##_update(_set_r_, value, max_); \ + CMC_(PFX, _update)(_set_r_, value, max_); \ } \ \ _set_r_->callbacks = _set1_->callbacks; \ @@ -917,13 +949,13 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return _set_r_; \ } \ \ - struct SNAME *PFX##_intersection(struct SNAME *_set1_, \ - struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ return NULL; \ @@ -932,17 +964,17 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " _set1_->count < _set2_->count ? _set1_ : _set2_; \ struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set_A_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - size_t m1 = PFX##_iter_multiplicity(&iter); \ - size_t m2 = PFX##_impl_multiplicity_of(_set_B_, value); \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \ size_t max_ = m1 < m2 ? m1 : m2; \ \ - PFX##_update(_set_r_, value, max_); \ + CMC_(PFX, _update)(_set_r_, value, max_); \ } \ \ _set_r_->callbacks = _set1_->callbacks; \ @@ -950,27 +982,28 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return _set_r_; \ } \ \ - struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ return NULL; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - size_t m1 = PFX##_iter_multiplicity(&iter); \ - size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ \ if (m1 > m2) \ - PFX##_update(_set_r_, value, m1 - m2); \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ } \ \ _set_r_->callbacks = _set1_->callbacks; \ @@ -978,29 +1011,34 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return _set_r_; \ } \ \ - struct SNAME *PFX##_summation(struct SNAME *_set1_, struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ return NULL; \ \ - struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \ - struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ \ - for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ { \ - PFX##_insert_many(_set_r_, PFX##_iter_value(&iter1), \ - PFX##_iter_multiplicity(&iter1)); \ + CMC_(PFX, _insert_many) \ + (_set_r_, CMC_(PFX, _iter_value)(&iter1), \ + CMC_(PFX, _iter_multiplicity)(&iter1)); \ } \ \ - for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ { \ - PFX##_insert_many(_set_r_, PFX##_iter_value(&iter2), \ - PFX##_iter_multiplicity(&iter2)); \ + CMC_(PFX, _insert_many) \ + (_set_r_, CMC_(PFX, _iter_value)(&iter2), \ + CMC_(PFX, _iter_multiplicity)(&iter2)); \ } \ \ _set_r_->callbacks = _set1_->callbacks; \ @@ -1008,48 +1046,50 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return _set_r_; \ } \ \ - struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ return NULL; \ - struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \ - struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ \ - for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ { \ - V value = PFX##_iter_value(&iter1); \ + V value = CMC_(PFX, _iter_value)(&iter1); \ \ - size_t m1 = PFX##_iter_multiplicity(&iter1); \ - size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ \ if (m1 != m2) \ { \ if (m1 > m2) \ - PFX##_update(_set_r_, value, m1 - m2); \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ else \ - PFX##_update(_set_r_, value, m2 - m1); \ + CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ } \ } \ \ - for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ { \ - V value = PFX##_iter_value(&iter2); \ + V value = CMC_(PFX, _iter_value)(&iter2); \ \ - size_t m1 = PFX##_impl_multiplicity_of(_set1_, value); \ - size_t m2 = PFX##_iter_multiplicity(&iter2); \ + size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ + size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ \ if (m1 != m2) \ { \ if (m1 > m2) \ - PFX##_update(_set_r_, value, m1 - m2); \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ else \ - PFX##_update(_set_r_, value, m2 - m1); \ + CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ } \ } \ \ @@ -1058,22 +1098,22 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return _set_r_; \ } \ \ - bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ if (_set1_->count > _set2_->count) \ return false; \ \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ return true; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - size_t m1 = PFX##_iter_multiplicity(&iter); \ - size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ \ if (m1 > m2) \ return false; \ @@ -1082,32 +1122,33 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ - return PFX##_is_subset(_set2_, _set1_); \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ } \ \ - bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ if (_set1_->count >= _set2_->count) \ return false; \ \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ { \ - if (!PFX##_empty(_set2_)) \ + if (!CMC_(PFX, _empty)(_set2_)) \ return true; \ else \ return false; \ } \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - size_t m1 = PFX##_iter_multiplicity(&iter); \ - size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ \ if (m1 >= m2) \ return false; \ @@ -1116,32 +1157,34 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - return PFX##_is_proper_subset(_set2_, _set1_); \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ } \ \ - bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ return true; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_entry(_set2_, value) != NULL) \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ return false; \ } \ \ return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ @@ -1149,9 +1192,9 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " iter.first = 0; \ iter.last = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ for (size_t i = 0; i < target->capacity; i++) \ { \ @@ -1177,19 +1220,19 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ iter.index = 0; \ iter.first = 0; \ iter.last = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ for (size_t i = 0; i < target->capacity; i++) \ { \ @@ -1216,24 +1259,24 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->first; \ iter->index = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ return true; \ } \ @@ -1241,13 +1284,13 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->last; \ iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->end = true; \ \ return true; \ @@ -1256,7 +1299,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -1267,9 +1310,10 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ - struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ \ iter->index++; \ \ @@ -1285,7 +1329,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -1296,9 +1340,10 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ - struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ \ iter->index--; \ \ @@ -1315,7 +1360,8 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -1330,13 +1376,14 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_next(iter); \ + CMC_(PFX, _iter_next)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -1351,50 +1398,53 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_prev(iter); \ + CMC_(PFX, _iter_prev)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor].value; \ } \ \ - size_t PFX##_iter_multiplicity(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return 0; \ \ return iter->target->buffer[iter->cursor].multiplicity; \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->index; \ } \ \ - static size_t PFX##_impl_multiplicity_of(struct SNAME *_set_, V value) \ + static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, \ + V value) \ { \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_set_, value); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_set_, value); \ \ if (!entry) \ return 0; \ @@ -1402,8 +1452,9 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return entry->multiplicity; \ } \ \ - static struct SNAME##_entry *PFX##_impl_insert_and_return( \ - struct SNAME *_set_, V value, bool *new_node) \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, \ + bool *new_node) \ { \ /* If the entry already exists simply return it as we might do */ \ /* something with it. This function only guarantees that there is */ \ @@ -1411,16 +1462,17 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " \ *new_node = false; \ \ - struct SNAME##_entry *entry = PFX##_impl_get_entry(_set_, value); \ + struct CMC_DEF_ENTRY(SNAME) *entry = \ + CMC_(PFX, _impl_get_entry)(_set_, value); \ \ if (entry != NULL) \ return entry; \ \ *new_node = true; \ \ - if (PFX##_full(_set_)) \ + if (CMC_(PFX, _full)(_set_)) \ { \ - if (!PFX##_resize(_set_, _set_->capacity + 1)) \ + if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \ return NULL; \ } \ \ @@ -1430,8 +1482,8 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " /* Current multiplicity. Might change due to robin hood hashing */ \ size_t curr_mul = 1; \ \ - struct SNAME##_entry *target = &(_set_->buffer[pos]); \ - struct SNAME##_entry *to_return = NULL; \ + struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ + struct CMC_DEF_ENTRY(SNAME) *to_return = NULL; \ \ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ { \ @@ -1488,13 +1540,13 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return to_return; \ } \ \ - static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \ - V value) \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ { \ size_t hash = _set_->f_val->hash(value); \ size_t pos = hash % _set_->capacity; \ \ - struct SNAME##_entry *target = &(_set_->buffer[pos]); \ + struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ \ while (target->state == CMC_ES_FILLED || \ target->state == CMC_ES_DELETED) \ @@ -1509,7 +1561,7 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return NULL; \ } \ \ - static size_t PFX##_impl_calculate_size(size_t required) \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ { \ const size_t count = \ sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ @@ -1524,4 +1576,4 @@ static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> " return cmc_hashtable_primes[i]; \ } -#endif /* CMC_HASHMULTISET_H */ +#endif /* CMC_CMC_HASHMULTISET_H */ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 086bc0e..1cbf3c0 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -16,8 +16,8 @@ * hood hashing. */ -#ifndef CMC_HASHSET_H -#define CMC_HASHSET_H +#ifndef CMC_CMC_HASHSET_H +#define CMC_CMC_HASHSET_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -33,200 +33,216 @@ * HashSet specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_hashset = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p }"; +static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p }"; -#define CMC_GENERATE_HASHSET(PFX, SNAME, V) \ - CMC_GENERATE_HASHSET_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_HASHSET_SOURCE(PFX, SNAME, V) +/** + * Core HashSet implementation + */ +#define CMC_CMC_HASHSET_CORE(BODY) \ + CMC_CMC_HASHSET_CORE_HEADER(BODY) \ + CMC_CMC_HASHSET_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_HASHSET_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHSET_HEADER(PFX, SNAME, V) +#define CMC_CMC_HASHSET_CORE_HEADER(BODY) \ + CMC_CMC_HASHSET_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_HASHSET_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_HASHSET_SOURCE(PFX, SNAME, V) +#define CMC_CMC_HASHSET_CORE_SOURCE(BODY) \ + CMC_CMC_HASHSET_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHSET_HEADER(PFX, SNAME, V) \ - \ - /* Hashset Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct SNAME##_entry *buffer; \ - \ - /* Current Array Capcity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - struct SNAME##_entry \ - { \ - /* Entry value */ \ - V value; \ - \ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ - \ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Hashset Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target Hashset */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_set_); \ - void PFX##_free(struct SNAME *_set_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_set_, V value); \ - bool PFX##_remove(struct SNAME *_set_, V value); \ - /* Element Access */ \ - bool PFX##_max(struct SNAME *_set_, V *value); \ - bool PFX##_min(struct SNAME *_set_, V *value); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_set_, V value); \ - bool PFX##_empty(struct SNAME *_set_); \ - bool PFX##_full(struct SNAME *_set_); \ - size_t PFX##_count(struct SNAME *_set_); \ - size_t PFX##_capacity(struct SNAME *_set_); \ - double PFX##_load(struct SNAME *_set_); \ - int PFX##_flag(struct SNAME *_set_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_set_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_); \ - bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_set_); \ - bool PFX##_print(struct SNAME *_set_, FILE *fptr); \ - \ - /* Set Operations */ \ - struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \ - struct SNAME *PFX##_intersection(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - struct SNAME *PFX##_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Hashset Structure */ \ + struct SNAME \ + { \ + /* Array of Entries */ \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ + \ + /* Current Array Capcity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry value */ \ + V value; \ + \ + /* The distance of this node to its original position, used by */ \ + /* robin-hood hashing */ \ + size_t dist; \ + \ + /* The sate of this node (DELETED, EMPTY, FILLED) */ \ + enum cmc_entry_state state; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Hashset Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target Hashset */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* The index of the first element */ \ + size_t first; \ + \ + /* The index of the last element */ \ + size_t last; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _set_); \ + void CMC_(PFX, _free)(struct SNAME * _set_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _set_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _set_); \ + bool CMC_(PFX, _full)(struct SNAME * _set_); \ + size_t CMC_(PFX, _count)(struct SNAME * _set_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ + double CMC_(PFX, _load)(struct SNAME * _set_); \ + int CMC_(PFX, _flag)(struct SNAME * _set_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \ + \ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HASHSET_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_HASHSET_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ - static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \ - V value); \ - static size_t PFX##_impl_calculate_size(size_t required); \ - static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_set_); \ - static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_set_); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ + static struct CMC_DEF_ITER(SNAME) \ + CMC_(PFX, _impl_it_start)(struct SNAME * _set_); \ + static struct CMC_DEF_ITER(SNAME) \ + CMC_(PFX, _impl_it_end)(struct SNAME * _set_); \ \ - struct SNAME *PFX##_new(size_t capacity, double load, \ - struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -240,7 +256,8 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " if (!f_val) \ return NULL; \ \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ \ struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ \ @@ -248,7 +265,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return NULL; \ \ _set_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \ + alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ \ if (!_set_->buffer) \ { \ @@ -259,7 +276,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " _set_->count = 0; \ _set_->capacity = real_capacity; \ _set_->load = load; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ _set_->f_val = f_val; \ _set_->alloc = alloc; \ _set_->callbacks = NULL; \ @@ -267,9 +284,9 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return _set_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, double load, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ @@ -281,7 +298,8 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " if (!f_val) \ return NULL; \ \ - size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \ + size_t real_capacity = \ + CMC_(PFX, _impl_calculate_size)(capacity / load); \ \ if (!alloc) \ alloc = &cmc_alloc_node_default; \ @@ -292,7 +310,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return NULL; \ \ _set_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \ + alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ \ if (!_set_->buffer) \ { \ @@ -303,7 +321,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " _set_->count = 0; \ _set_->capacity = real_capacity; \ _set_->load = load; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ _set_->f_val = f_val; \ _set_->alloc = alloc; \ _set_->callbacks = callbacks; \ @@ -311,13 +329,13 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return _set_; \ } \ \ - void PFX##_clear(struct SNAME *_set_) \ + void CMC_(PFX, _clear)(struct SNAME * _set_) \ { \ if (_set_->f_val->free) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ - struct SNAME##_entry *entry = &(_set_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ \ if (entry->state == CMC_ES_FILLED) \ { \ @@ -327,19 +345,19 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " } \ \ memset(_set_->buffer, 0, \ - sizeof(struct SNAME##_entry) * _set_->capacity); \ + sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ \ _set_->count = 0; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_set_) \ + void CMC_(PFX, _free)(struct SNAME * _set_) \ { \ if (_set_->f_val->free) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ - struct SNAME##_entry *entry = &(_set_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ \ if (entry->state == CMC_ES_FILLED) \ { \ @@ -352,8 +370,9 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " _set_->alloc->free(_set_); \ } \ \ - void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _set_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ @@ -362,20 +381,20 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " \ _set_->callbacks = callbacks; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_insert(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ { \ - if (PFX##_full(_set_)) \ + if (CMC_(PFX, _full)(_set_)) \ { \ - if (!PFX##_resize(_set_, _set_->capacity + 1)) \ + if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \ return false; \ } \ \ - if (PFX##_impl_get_entry(_set_, value) != NULL) \ + if (CMC_(PFX, _impl_get_entry)(_set_, value) != NULL) \ { \ - _set_->flag = cmc_flags.DUPLICATE; \ + _set_->flag = CMC_FLAG_DUPLICATE; \ return false; \ } \ \ @@ -383,7 +402,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " size_t original_pos = hash % _set_->capacity; \ size_t pos = original_pos; \ \ - struct SNAME##_entry *target = &(_set_->buffer[pos]); \ + struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ \ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ { \ @@ -422,7 +441,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " } \ \ _set_->count++; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->create) \ _set_->callbacks->create(); \ @@ -430,19 +449,20 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_remove(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, value); \ + struct CMC_DEF_ENTRY(SNAME) *result = \ + CMC_(PFX, _impl_get_entry)(_set_, value); \ \ if (result == NULL) \ { \ - _set_->flag = cmc_flags.NOT_FOUND; \ + _set_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ @@ -451,7 +471,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " result->state = CMC_ES_DELETED; \ \ _set_->count--; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->delete) \ _set_->callbacks->delete (); \ @@ -459,22 +479,22 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_max(struct SNAME *_set_, V *value) \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ V max_value; \ - struct SNAME##_iter iter = PFX##_iter_start(_set_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V result = PFX##_iter_value(&iter); \ - size_t index = PFX##_iter_index(&iter); \ + V result = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ \ if (index == 0) \ max_value = result; \ @@ -485,7 +505,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " if (value) \ *value = max_value; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -493,22 +513,22 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_min(struct SNAME *_set_, V *value) \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ V min_value; \ - struct SNAME##_iter iter = PFX##_iter_start(_set_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V result = PFX##_iter_value(&iter); \ - size_t index = PFX##_iter_index(&iter); \ + V result = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ \ if (index == 0) \ min_value = result; \ @@ -519,7 +539,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " if (value) \ *value = min_value; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -527,11 +547,11 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_contains(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ { \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ - bool result = PFX##_impl_get_entry(_set_, value) != NULL; \ + bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -539,39 +559,39 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_set_) \ + bool CMC_(PFX, _empty)(struct SNAME * _set_) \ { \ return _set_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_set_) \ + bool CMC_(PFX, _full)(struct SNAME * _set_) \ { \ return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ } \ \ - size_t PFX##_count(struct SNAME *_set_) \ + size_t CMC_(PFX, _count)(struct SNAME * _set_) \ { \ return _set_->count; \ } \ \ - size_t PFX##_capacity(struct SNAME *_set_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \ { \ return _set_->capacity; \ } \ \ - double PFX##_load(struct SNAME *_set_) \ + double CMC_(PFX, _load)(struct SNAME * _set_) \ { \ return _set_->load; \ } \ \ - int PFX##_flag(struct SNAME *_set_) \ + int CMC_(PFX, _flag)(struct SNAME * _set_) \ { \ return _set_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_set_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \ { \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->capacity == capacity) \ goto success; \ @@ -582,51 +602,51 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " /* Prevent integer overflow */ \ if (capacity >= UINTMAX_MAX * _set_->load) \ { \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = PFX##_impl_calculate_size(capacity); \ + size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ \ /* Not possible to shrink with current available prime numbers */ \ if (theoretical_size < _set_->count / _set_->load) \ { \ - _set_->flag = cmc_flags.INVALID; \ + _set_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ /* No callbacks since _new_set_ is just a temporary hashtable */ \ - struct SNAME *_new_set_ = PFX##_new_custom( \ + struct SNAME *_new_set_ = CMC_(PFX, _new_custom)( \ capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \ \ if (!_new_set_) \ { \ - _set_->flag = cmc_flags.ALLOC; \ + _set_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO turn this into a normal loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ /* TODO check for error */ \ - PFX##_insert(_new_set_, value); \ + CMC_(PFX, _insert)(_new_set_, value); \ } \ \ /* Unlikely */ \ if (_set_->count != _new_set_->count) \ { \ - PFX##_free(_new_set_); \ + CMC_(PFX, _free)(_new_set_); \ \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ - struct SNAME##_entry *tmp_b = _set_->buffer; \ + struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \ _set_->buffer = _new_set_->buffer; \ _new_set_->buffer = tmp_b; \ \ @@ -635,9 +655,9 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " _new_set_->capacity = tmp_c; \ \ /* Prevent the set from freeing the data */ \ - _new_set_->f_val = &(struct SNAME##_fval){ NULL }; \ + _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ \ - PFX##_free(_new_set_); \ + CMC_(PFX, _free)(_new_set_); \ \ success: \ \ @@ -647,15 +667,15 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ { \ - struct SNAME *result = \ - PFX##_new_custom(_set_->capacity * _set_->load, _set_->load, \ - _set_->f_val, _set_->alloc, _set_->callbacks); \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _set_->capacity * _set_->load, _set_->load, _set_->f_val, \ + _set_->alloc, _set_->callbacks); \ \ if (!result) \ { \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ @@ -663,11 +683,12 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ - struct SNAME##_entry *scan = &(_set_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \ \ if (scan->state != CMC_ES_EMPTY) \ { \ - struct SNAME##_entry *target = &(result->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *target = \ + &(result->buffer[i]); \ \ if (scan->state == CMC_ES_DELETED) \ target->state = CMC_ES_DELETED; \ @@ -683,19 +704,19 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " } \ else \ memcpy(result->buffer, _set_->buffer, \ - sizeof(struct SNAME##_entry) * _set_->capacity); \ + sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ \ result->count = _set_->count; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ - _set1_->flag = cmc_flags.OK; \ - _set2_->flag = cmc_flags.OK; \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ \ if (_set1_->count != _set2_->count) \ return false; \ @@ -703,36 +724,37 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " if (_set1_->count == 0) \ return true; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ /* TODO optimize this loop */ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - if (PFX##_impl_get_entry(_set2_, PFX##_iter_value(&iter)) == NULL) \ + if (CMC_(PFX, _impl_get_entry)( \ + _set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ return false; \ } \ \ return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_set_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \ { \ struct cmc_string str; \ struct SNAME *s_ = _set_; \ \ int n = \ - snprintf(str.s, cmc_string_len, cmc_string_fmt_hashset, #SNAME, \ - #V, s_, s_->buffer, s_->capacity, s_->count, s_->load, \ - s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ + snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashset, \ + #SNAME, #V, s_, s_->buffer, s_->capacity, s_->count, \ + s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_set_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \ { \ for (size_t i = 0; i < _set_->capacity; i++) \ { \ - struct SNAME##_entry *entry = &(_set_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ \ if (entry->state == CMC_ES_FILLED) \ { \ @@ -744,32 +766,35 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ { \ - _set1_->flag = cmc_flags.ALLOC; \ - _set2_->flag = cmc_flags.ALLOC; \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ - struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \ - struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ \ /* TODO turn this into a normal loop and check for errors */ \ - for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ { \ - PFX##_insert(_set_r_, PFX##_iter_value(&iter1)); \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ } \ \ - for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ { \ - PFX##_insert(_set_r_, PFX##_iter_value(&iter2)); \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ } \ \ _set_r_->callbacks = _set1_->callbacks; \ @@ -777,18 +802,18 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return _set_r_; \ } \ \ - struct SNAME *PFX##_intersection(struct SNAME *_set1_, \ - struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ { \ - _set1_->flag = cmc_flags.ALLOC; \ - _set2_->flag = cmc_flags.ALLOC; \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ @@ -796,14 +821,14 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " _set1_->count < _set2_->count ? _set1_ : _set2_; \ struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set_A_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_entry(_set_B_, value) != NULL) \ - PFX##_insert(_set_r_, value); \ + if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ } \ \ _set_r_->callbacks = _set1_->callbacks; \ @@ -811,28 +836,29 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return _set_r_; \ } \ \ - struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ { \ - _set1_->flag = cmc_flags.ALLOC; \ - _set2_->flag = cmc_flags.ALLOC; \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_entry(_set2_, value) == NULL) \ - PFX##_insert(_set_r_, value); \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ } \ \ _set_r_->callbacks = _set1_->callbacks; \ @@ -840,38 +866,40 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return _set_r_; \ } \ \ - struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* Callbacks are added later */ \ struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \ - _set1_->alloc, NULL); \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ \ if (!_set_r_) \ { \ - _set1_->flag = cmc_flags.ALLOC; \ - _set2_->flag = cmc_flags.ALLOC; \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ - struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \ - struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ \ - for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ { \ - V value = PFX##_iter_value(&iter1); \ + V value = CMC_(PFX, _iter_value)(&iter1); \ \ - if (PFX##_impl_get_entry(_set2_, value) == NULL) \ - PFX##_insert(_set_r_, value); \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ } \ \ - for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ { \ - V value = PFX##_iter_value(&iter2); \ + V value = CMC_(PFX, _iter_value)(&iter2); \ \ - if (PFX##_impl_get_entry(_set1_, value) == NULL) \ - PFX##_insert(_set_r_, value); \ + if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ } \ \ _set_r_->callbacks = _set1_->callbacks; \ @@ -882,10 +910,10 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " /* Is _set1_ a subset of _set2_ ? */ \ /* A set X is a subset of a set Y when: X <= Y */ \ /* If X is a subset of Y, then Y is a superset of X */ \ - bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ - _set1_->flag = cmc_flags.OK; \ - _set2_->flag = cmc_flags.OK; \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ \ /* If the cardinality of _set1_ is greater than that of _set2_, */ \ /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ @@ -893,16 +921,16 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return false; \ \ /* The empty set is a subset of all sets */ \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ return true; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_entry(_set2_, value) == NULL) \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ return false; \ } \ \ @@ -912,18 +940,19 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " /* Is _set1_ a superset of _set2_ ? */ \ /* A set X is a superset of a set Y when: X >= Y */ \ /* If X is a superset of Y, then Y is a subset of X */ \ - bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ - return PFX##_is_subset(_set2_, _set1_); \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ } \ \ /* Is _set1_ a proper subset of _set2_ ? */ \ /* A set X is a proper subset of a set Y when: X < Y */ \ /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - _set1_->flag = cmc_flags.OK; \ - _set2_->flag = cmc_flags.OK; \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ \ /* If the cardinality of _set1_ is greater than or equal to that of */ \ /* _set2_, then it is safe to say that _set1_ can't be a proper */ \ @@ -931,10 +960,10 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " if (_set1_->count >= _set2_->count) \ return false; \ \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ { \ /* The empty set is a proper subset of all non-empty sets */ \ - if (!PFX##_empty(_set2_)) \ + if (!CMC_(PFX, _empty)(_set2_)) \ return true; \ /* The empty set is not a proper subset of itself (this is true */ \ /* for any set) */ \ @@ -942,13 +971,13 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return false; \ } \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_entry(_set2_, value) == NULL) \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ return false; \ } \ \ @@ -958,40 +987,42 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " /* Is _set1_ a proper superset of _set2_ ? */ \ /* A set X is a proper superset of a set Y when: X > Y */ \ /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - return PFX##_is_proper_subset(_set2_, _set1_); \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ } \ \ /* Is _set1_ a disjointset of _set2_ ? */ \ /* A set X is a disjointset of a set Y if their intersection is empty, */ \ /* that is, if there are no elements in common between the two */ \ - bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - _set1_->flag = cmc_flags.OK; \ - _set2_->flag = cmc_flags.OK; \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ \ /* The intersection of an empty set with any other set will result */ \ /* in an empty set */ \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ return true; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_entry(_set2_, value) != NULL) \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ return false; \ } \ \ return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ @@ -999,9 +1030,9 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " iter.first = 0; \ iter.last = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ for (size_t i = 0; i < target->capacity; i++) \ { \ @@ -1027,19 +1058,19 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ iter.index = 0; \ iter.first = 0; \ iter.last = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ for (size_t i = 0; i < target->capacity; i++) \ { \ @@ -1066,24 +1097,24 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->first; \ iter->index = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ return true; \ } \ @@ -1091,13 +1122,13 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->last; \ iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->end = true; \ \ return true; \ @@ -1106,7 +1137,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -1117,9 +1148,10 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ - struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ \ iter->index++; \ \ @@ -1135,7 +1167,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -1146,9 +1178,10 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ - struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ \ iter->index--; \ \ @@ -1165,7 +1198,8 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -1180,13 +1214,14 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_next(iter); \ + CMC_(PFX, _iter_next)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -1201,46 +1236,47 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_prev(iter); \ + CMC_(PFX, _iter_prev)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor].value; \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->index; \ } \ \ - static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \ - V value) \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ { \ size_t hash = _set_->f_val->hash(value); \ size_t pos = hash % _set_->capacity; \ \ - struct SNAME##_entry *target = &(_set_->buffer[pos]); \ + struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ \ while (target->state == CMC_ES_FILLED || \ target->state == CMC_ES_DELETED) \ @@ -1255,7 +1291,7 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return NULL; \ } \ \ - static size_t PFX##_impl_calculate_size(size_t required) \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ { \ const size_t count = \ sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ @@ -1270,4 +1306,4 @@ static const char *cmc_string_fmt_hashset = "struct %s<%s> " return cmc_hashtable_primes[i]; \ } -#endif /* CMC_HASHSET_H */ +#endif /* CMC_CMC_HASHSET_H */ diff --git a/src/cmc/heap.h b/src/cmc/heap.h index 0effac2..71fbaf7 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -27,8 +27,8 @@ * - min/max : Accesses the min/max element from the heap */ -#ifndef CMC_HEAP_H -#define CMC_HEAP_H +#ifndef CMC_CMC_HEAP_H +#define CMC_CMC_HEAP_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -55,159 +55,171 @@ enum cmc_heap_order * Heap specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_heap = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "type:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p}"; +static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "type:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p}"; -#define CMC_GENERATE_HEAP(PFX, SNAME, V) \ - CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) +/** + * Core Heap implementation + */ +#define CMC_CMC_HEAP_CORE(BODY) \ + CMC_CMC_HEAP_CORE_HEADER(BODY) \ + CMC_CMC_HEAP_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_HEAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) +#define CMC_CMC_HEAP_CORE_HEADER(BODY) \ + CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_HEAP_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) +#define CMC_CMC_HEAP_CORE_SOURCE(BODY) \ + CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \ - \ - /* Heap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements in the heap */ \ - size_t count; \ - \ - /* Heap order (MaxHeap or MinHeap) */ \ - enum cmc_heap_order HO; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Heap Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target heap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, enum cmc_heap_order HO, \ - struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, enum cmc_heap_order HO, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_heap_); \ - void PFX##_free(struct SNAME *_heap_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_heap_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_heap_, V value); \ - bool PFX##_remove(struct SNAME *_heap_); \ - /* Element Access */ \ - V PFX##_peek(struct SNAME *_heap_); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_heap_, V value); \ - bool PFX##_empty(struct SNAME *_heap_); \ - bool PFX##_full(struct SNAME *_heap_); \ - size_t PFX##_count(struct SNAME *_heap_); \ - size_t PFX##_capacity(struct SNAME *_heap_); \ - int PFX##_flag(struct SNAME *_heap_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_heap_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_heap_); \ - bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_heap_); \ - bool PFX##_print(struct SNAME *_heap_, FILE *fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Heap Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements in the heap */ \ + size_t count; \ + \ + /* Heap order (MaxHeap or MinHeap) */ \ + enum cmc_heap_order HO; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Heap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target heap */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, enum cmc_heap_order HO, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _heap_); \ + void CMC_(PFX, _free)(struct SNAME * _heap_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _heap_); \ + /* Element Access */ \ + V CMC_(PFX, _peek)(struct SNAME * _heap_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ + bool CMC_(PFX, _full)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ + int CMC_(PFX, _flag)(struct SNAME * _heap_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_); \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_HEAP_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ - static void PFX##_impl_float_up(struct SNAME *_heap_, size_t index); \ - static void PFX##_impl_float_down(struct SNAME *_heap_, size_t index); \ + static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, \ + size_t index); \ + static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, \ + size_t index); \ \ - struct SNAME *PFX##_new(size_t capacity, enum cmc_heap_order HO, \ - struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -236,7 +248,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " _heap_->capacity = capacity; \ _heap_->count = 0; \ _heap_->HO = HO; \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ _heap_->f_val = f_val; \ _heap_->alloc = alloc; \ _heap_->callbacks = NULL; \ @@ -244,9 +256,10 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return _heap_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, enum cmc_heap_order HO, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, enum cmc_heap_order HO, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (capacity < 1) \ return NULL; \ @@ -276,7 +289,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " _heap_->capacity = capacity; \ _heap_->count = 0; \ _heap_->HO = HO; \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ _heap_->f_val = f_val; \ _heap_->alloc = alloc; \ _heap_->callbacks = callbacks; \ @@ -284,7 +297,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return _heap_; \ } \ \ - void PFX##_clear(struct SNAME *_heap_) \ + void CMC_(PFX, _clear)(struct SNAME * _heap_) \ { \ if (_heap_->f_val->free) \ { \ @@ -297,10 +310,10 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \ \ _heap_->count = 0; \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_heap_) \ + void CMC_(PFX, _free)(struct SNAME * _heap_) \ { \ if (_heap_->f_val->free) \ { \ @@ -314,8 +327,9 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " _heap_->alloc->free(_heap_); \ } \ \ - void PFX##_customize(struct SNAME *_heap_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _heap_->alloc = &cmc_alloc_node_default; \ @@ -324,14 +338,14 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " \ _heap_->callbacks = callbacks; \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_insert(struct SNAME *_heap_, V value) \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \ { \ - if (PFX##_full(_heap_)) \ + if (CMC_(PFX, _full)(_heap_)) \ { \ - if (!PFX##_resize(_heap_, _heap_->count * 2)) \ + if (!CMC_(PFX, _resize)(_heap_, _heap_->count * 2)) \ return false; \ } \ \ @@ -339,10 +353,10 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " \ if (_heap_->count > 1) \ { \ - PFX##_impl_float_up(_heap_, _heap_->count - 1); \ + CMC_(PFX, _impl_float_up)(_heap_, _heap_->count - 1); \ } \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->create) \ _heap_->callbacks->create(); \ @@ -350,11 +364,11 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return true; \ } \ \ - bool PFX##_remove(struct SNAME *_heap_) \ + bool CMC_(PFX, _remove)(struct SNAME * _heap_) \ { \ - if (PFX##_empty(_heap_)) \ + if (CMC_(PFX, _empty)(_heap_)) \ { \ - _heap_->flag = cmc_flags.EMPTY; \ + _heap_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -363,9 +377,9 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " \ _heap_->count--; \ \ - PFX##_impl_float_down(_heap_, 0); \ + CMC_(PFX, _impl_float_down)(_heap_, 0); \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->delete) \ _heap_->callbacks->delete (); \ @@ -373,15 +387,15 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return true; \ } \ \ - V PFX##_peek(struct SNAME *_heap_) \ + V CMC_(PFX, _peek)(struct SNAME * _heap_) \ { \ - if (PFX##_empty(_heap_)) \ + if (CMC_(PFX, _empty)(_heap_)) \ { \ - _heap_->flag = cmc_flags.EMPTY; \ + _heap_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->read) \ _heap_->callbacks->read(); \ @@ -389,9 +403,9 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return _heap_->buffer[0]; \ } \ \ - bool PFX##_contains(struct SNAME *_heap_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \ { \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ bool result = false; \ \ @@ -410,41 +424,41 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_heap_) \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_) \ { \ return _heap_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_heap_) \ + bool CMC_(PFX, _full)(struct SNAME * _heap_) \ { \ return _heap_->count >= _heap_->capacity; \ } \ \ - size_t PFX##_count(struct SNAME *_heap_) \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_) \ { \ return _heap_->count; \ } \ \ - size_t PFX##_capacity(struct SNAME *_heap_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \ { \ return _heap_->capacity; \ } \ \ - int PFX##_flag(struct SNAME *_heap_) \ + int CMC_(PFX, _flag)(struct SNAME * _heap_) \ { \ return _heap_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_heap_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \ { \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->capacity == capacity) \ goto success; \ \ if (capacity < _heap_->count) \ { \ - _heap_->flag = cmc_flags.INVALID; \ + _heap_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ @@ -453,7 +467,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " \ if (!new_buffer) \ { \ - _heap_->flag = cmc_flags.ALLOC; \ + _heap_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -470,15 +484,15 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_heap_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \ { \ - struct SNAME *result = \ - PFX##_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, \ - _heap_->alloc, _heap_->callbacks); \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, \ + _heap_->callbacks); \ \ if (!result) \ { \ - _heap_->flag = cmc_flags.ERROR; \ + _heap_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ @@ -492,15 +506,15 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " \ result->count = _heap_->count; \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \ { \ - _heap1_->flag = cmc_flags.OK; \ - _heap2_->flag = cmc_flags.OK; \ + _heap1_->flag = CMC_FLAG_OK; \ + _heap2_->flag = CMC_FLAG_OK; \ \ if (_heap1_->count != _heap2_->count) \ return false; \ @@ -515,20 +529,20 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_heap_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_) \ { \ struct cmc_string str; \ struct SNAME *h_ = _heap_; \ const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_heap, #SNAME, \ - #V, h_, h_->buffer, h_->capacity, h_->count, t, \ - h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_heap, \ + #SNAME, #V, h_, h_->buffer, h_->capacity, h_->count, \ + t, h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_heap_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr) \ { \ for (size_t i = 0; i < _heap_->count; i++) \ { \ @@ -539,50 +553,50 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ iter.cursor = target->count - 1; \ \ return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ return true; \ } \ @@ -590,12 +604,12 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->end = true; \ \ return true; \ @@ -604,7 +618,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -615,14 +629,14 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor++; \ \ return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -633,7 +647,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor--; \ \ @@ -641,7 +655,8 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -658,7 +673,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " if (iter->end) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor += steps; \ \ @@ -666,7 +681,8 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -680,7 +696,7 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " if (steps == 0 || iter->cursor < steps) \ return false; \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor -= steps; \ \ @@ -689,33 +705,34 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->cursor > index) \ - return PFX##_iter_rewind(iter, iter->cursor - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ else if (iter->cursor < index) \ - return PFX##_iter_advance(iter, index - iter->cursor); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor]; \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->cursor; \ } \ \ - static void PFX##_impl_float_up(struct SNAME *_heap_, size_t index) \ + static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, size_t index) \ { \ /* Current index */ \ size_t C = index; \ @@ -743,7 +760,8 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " } \ } \ \ - static void PFX##_impl_float_down(struct SNAME *_heap_, size_t index) \ + static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, \ + size_t index) \ { \ int mod = _heap_->HO; \ \ @@ -784,4 +802,4 @@ static const char *cmc_string_fmt_heap = "struct %s<%s> " } \ } -#endif /* CMC_HEAP_H */ +#endif /* CMC_CMC_HEAP_H */ diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index 2b99a30..db61308 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -18,8 +18,8 @@ * - O(log n) - Remove Max */ -#ifndef CMC_INTERVALHEAP_H -#define CMC_INTERVALHEAP_H +#ifndef CMC_CMC_INTERVALHEAP_H +#define CMC_CMC_INTERVALHEAP_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -30,165 +30,176 @@ * IntervalHeap specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "size:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "size:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_INTERVALHEAP(PFX, SNAME, V) \ - CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V) +/** + * Core IntervalHeap implementation + */ +#define CMC_CMC_INTERVALHEAP_CORE(BODY) \ + CMC_CMC_INTERVALHEAP_CORE_HEADER(BODY) \ + CMC_CMC_INTERVALHEAP_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_INTERVALHEAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V) +#define CMC_CMC_INTERVALHEAP_CORE_HEADER(BODY) \ + CMC_CMC_INTERVALHEAP_CORE_HEADER_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_INTERVALHEAP_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V) +#define CMC_CMC_INTERVALHEAP_CORE_SOURCE(BODY) \ + CMC_CMC_INTERVALHEAP_CORE_SOURCE_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V) \ - \ - /* Heap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ - V (*buffer)[2]; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of pairs of values in the array */ \ - size_t size; \ - \ - /* Current amount of elements in the heap */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Heap Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target heap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_heap_); \ - void PFX##_free(struct SNAME *_heap_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_heap_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_heap_, V value); \ - bool PFX##_remove_max(struct SNAME *_heap_); \ - bool PFX##_remove_min(struct SNAME *_heap_); \ - /* Collection Update */ \ - bool PFX##_update_max(struct SNAME *_heap_, V value); \ - bool PFX##_update_min(struct SNAME *_heap_, V value); \ - /* Element Access */ \ - V PFX##_max(struct SNAME *_heap_); \ - V PFX##_min(struct SNAME *_heap_); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_heap_, V value); \ - bool PFX##_empty(struct SNAME *_heap_); \ - bool PFX##_full(struct SNAME *_heap_); \ - size_t PFX##_count(struct SNAME *_heap_); \ - size_t PFX##_capacity(struct SNAME *_heap_); \ - int PFX##_flag(struct SNAME *_heap_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_heap_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_); \ - bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_heap_); \ - bool PFX##_print(struct SNAME *_heap_, FILE *fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Heap Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ + V (*buffer)[2]; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of pairs of values in the array */ \ + size_t size; \ + \ + /* Current amount of elements in the heap */ \ + size_t count; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Heap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target heap */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _heap_); \ + void CMC_(PFX, _free)(struct SNAME * _heap_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _remove_max)(struct SNAME * _heap_); \ + bool CMC_(PFX, _remove_min)(struct SNAME * _heap_); \ + /* Collection Update */ \ + bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value); \ + /* Element Access */ \ + V CMC_(PFX, _max)(struct SNAME * _heap_); \ + V CMC_(PFX, _min)(struct SNAME * _heap_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ + bool CMC_(PFX, _full)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ + int CMC_(PFX, _flag)(struct SNAME * _heap_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_); \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_INTERVALHEAP_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ - static void PFX##_impl_float_up_max(struct SNAME *_heap_); \ - static void PFX##_impl_float_up_min(struct SNAME *_heap_); \ - static void PFX##_impl_float_down_max(struct SNAME *_heap_); \ - static void PFX##_impl_float_down_min(struct SNAME *_heap_); \ + static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_); \ + static void CMC_(PFX, _impl_float_up_min)(struct SNAME * _heap_); \ + static void CMC_(PFX, _impl_float_down_max)(struct SNAME * _heap_); \ + static void CMC_(PFX, _impl_float_down_min)(struct SNAME * _heap_); \ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -216,7 +227,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " _heap_->capacity = capacity; \ _heap_->size = 0; \ _heap_->count = 0; \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ _heap_->f_val = f_val; \ _heap_->alloc = alloc; \ _heap_->callbacks = NULL; \ @@ -224,9 +235,9 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return _heap_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ if (capacity == 0 || capacity == UINTMAX_MAX) \ return NULL; \ @@ -255,7 +266,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " _heap_->capacity = capacity; \ _heap_->size = 0; \ _heap_->count = 0; \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ _heap_->f_val = f_val; \ _heap_->alloc = alloc; \ _heap_->callbacks = callbacks; \ @@ -263,7 +274,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return _heap_; \ } \ \ - void PFX##_clear(struct SNAME *_heap_) \ + void CMC_(PFX, _clear)(struct SNAME * _heap_) \ { \ if (_heap_->f_val->free) \ { \ @@ -277,10 +288,10 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " \ _heap_->size = 0; \ _heap_->count = 0; \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_heap_) \ + void CMC_(PFX, _free)(struct SNAME * _heap_) \ { \ if (_heap_->f_val->free) \ { \ @@ -295,8 +306,9 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " _heap_->alloc->free(_heap_); \ } \ \ - void PFX##_customize(struct SNAME *_heap_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _heap_->alloc = &cmc_alloc_node_default; \ @@ -305,14 +317,14 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " \ _heap_->callbacks = callbacks; \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_insert(struct SNAME *_heap_, V value) \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \ { \ - if (PFX##_full(_heap_)) \ + if (CMC_(PFX, _full)(_heap_)) \ { \ - if (!PFX##_resize(_heap_, _heap_->capacity * 4)) \ + if (!CMC_(PFX, _resize)(_heap_, _heap_->capacity * 4)) \ return false; \ } \ \ @@ -343,7 +355,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " } \ \ _heap_->count++; \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->count > 2) \ { \ @@ -353,9 +365,9 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " V(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); \ \ if (_heap_->f_val->cmp((*parent)[0], value) > 0) \ - PFX##_impl_float_up_min(_heap_); \ + CMC_(PFX, _impl_float_up_min)(_heap_); \ else if (_heap_->f_val->cmp((*parent)[1], value) < 0) \ - PFX##_impl_float_up_max(_heap_); \ + CMC_(PFX, _impl_float_up_max)(_heap_); \ /* else no float up required */ \ } \ \ @@ -365,11 +377,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - bool PFX##_remove_max(struct SNAME *_heap_) \ + bool CMC_(PFX, _remove_max)(struct SNAME * _heap_) \ { \ - if (PFX##_empty(_heap_)) \ + if (CMC_(PFX, _empty)(_heap_)) \ { \ - _heap_->flag = cmc_flags.EMPTY; \ + _heap_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -406,11 +418,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " _heap_->count--; \ \ /* FLoat Down on the MaxHeap */ \ - PFX##_impl_float_down_max(_heap_); \ + CMC_(PFX, _impl_float_down_max)(_heap_); \ \ success: \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->delete) \ _heap_->callbacks->delete (); \ @@ -418,11 +430,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - bool PFX##_remove_min(struct SNAME *_heap_) \ + bool CMC_(PFX, _remove_min)(struct SNAME * _heap_) \ { \ - if (PFX##_empty(_heap_)) \ + if (CMC_(PFX, _empty)(_heap_)) \ { \ - _heap_->flag = cmc_flags.EMPTY; \ + _heap_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -459,11 +471,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " _heap_->count--; \ \ /* FLoat Down on the MinHeap */ \ - PFX##_impl_float_down_min(_heap_); \ + CMC_(PFX, _impl_float_down_min)(_heap_); \ \ success: \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->delete) \ _heap_->callbacks->delete (); \ @@ -471,11 +483,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - bool PFX##_update_max(struct SNAME *_heap_, V value) \ + bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value) \ { \ - if (PFX##_empty(_heap_)) \ + if (CMC_(PFX, _empty)(_heap_)) \ { \ - _heap_->flag = cmc_flags.EMPTY; \ + _heap_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -490,17 +502,17 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " _heap_->buffer[0][1] = _heap_->buffer[0][0]; \ _heap_->buffer[0][0] = value; \ \ - PFX##_impl_float_down_max(_heap_); \ + CMC_(PFX, _impl_float_down_max)(_heap_); \ } \ else \ { \ /* Update Max element and float it down */ \ _heap_->buffer[0][1] = value; \ \ - PFX##_impl_float_down_max(_heap_); \ + CMC_(PFX, _impl_float_down_max)(_heap_); \ } \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->update) \ _heap_->callbacks->update(); \ @@ -508,11 +520,11 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - bool PFX##_update_min(struct SNAME *_heap_, V value) \ + bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value) \ { \ - if (PFX##_empty(_heap_)) \ + if (CMC_(PFX, _empty)(_heap_)) \ { \ - _heap_->flag = cmc_flags.EMPTY; \ + _heap_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -527,17 +539,17 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " _heap_->buffer[0][0] = _heap_->buffer[0][1]; \ _heap_->buffer[0][1] = value; \ \ - PFX##_impl_float_down_min(_heap_); \ + CMC_(PFX, _impl_float_down_min)(_heap_); \ } \ else \ { \ /* Update Min element and float it down */ \ _heap_->buffer[0][0] = value; \ \ - PFX##_impl_float_down_min(_heap_); \ + CMC_(PFX, _impl_float_down_min)(_heap_); \ } \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->update) \ _heap_->callbacks->update(); \ @@ -545,15 +557,15 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - V PFX##_max(struct SNAME *_heap_) \ + V CMC_(PFX, _max)(struct SNAME * _heap_) \ { \ - if (PFX##_empty(_heap_)) \ + if (CMC_(PFX, _empty)(_heap_)) \ { \ - _heap_->flag = cmc_flags.EMPTY; \ + _heap_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->read) \ _heap_->callbacks->read(); \ @@ -566,15 +578,15 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return _heap_->buffer[0][1]; \ } \ \ - V PFX##_min(struct SNAME *_heap_) \ + V CMC_(PFX, _min)(struct SNAME * _heap_) \ { \ - if (PFX##_empty(_heap_)) \ + if (CMC_(PFX, _empty)(_heap_)) \ { \ - _heap_->flag = cmc_flags.EMPTY; \ + _heap_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->read) \ _heap_->callbacks->read(); \ @@ -582,9 +594,9 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return _heap_->buffer[0][0]; \ } \ \ - bool PFX##_contains(struct SNAME *_heap_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \ { \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ bool result = false; \ \ @@ -603,47 +615,47 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_heap_) \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_) \ { \ return _heap_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_heap_) \ + bool CMC_(PFX, _full)(struct SNAME * _heap_) \ { \ /* The heap is full if all nodes are completely filled */ \ return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; \ } \ \ - size_t PFX##_count(struct SNAME *_heap_) \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_) \ { \ return _heap_->count; \ } \ \ - size_t PFX##_capacity(struct SNAME *_heap_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \ { \ return _heap_->capacity; \ } \ \ - int PFX##_flag(struct SNAME *_heap_) \ + int CMC_(PFX, _flag)(struct SNAME * _heap_) \ { \ return _heap_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_heap_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \ { \ if (_heap_->capacity == capacity) \ goto success; \ \ if (capacity < _heap_->count) \ { \ - _heap_->flag = cmc_flags.INVALID; \ + _heap_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ /* Prevent overflow */ \ if (capacity == UINTMAX_MAX) \ { \ - _heap_->flag = cmc_flags.ERROR; \ + _heap_->flag = CMC_FLAG_ERROR; \ return false; \ } \ \ @@ -654,7 +666,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " \ if (!new_buffer) \ { \ - _heap_->flag = cmc_flags.ALLOC; \ + _heap_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -669,7 +681,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " \ success: \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ if (_heap_->callbacks && _heap_->callbacks->resize) \ _heap_->callbacks->resize(); \ @@ -677,13 +689,13 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_heap_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \ { \ struct SNAME *result = _heap_->alloc->malloc(sizeof(struct SNAME)); \ \ if (!result) \ { \ - _heap_->flag = cmc_flags.ALLOC; \ + _heap_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ @@ -695,7 +707,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " if (!result->buffer) \ { \ _heap_->alloc->free(result); \ - _heap_->flag = cmc_flags.ALLOC; \ + _heap_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ @@ -712,20 +724,20 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " result->capacity = _heap_->capacity; \ result->size = _heap_->size; \ result->count = _heap_->count; \ - result->flag = cmc_flags.OK; \ + result->flag = CMC_FLAG_OK; \ result->f_val = _heap_->f_val; \ result->alloc = _heap_->alloc; \ result->callbacks = _heap_->callbacks; \ \ - _heap_->flag = cmc_flags.OK; \ + _heap_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \ { \ - _heap1_->flag = cmc_flags.OK; \ - _heap2_->flag = cmc_flags.OK; \ + _heap1_->flag = CMC_FLAG_OK; \ + _heap2_->flag = CMC_FLAG_OK; \ \ if (_heap1_->count != _heap2_->count) \ return false; \ @@ -742,20 +754,20 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_heap_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_) \ { \ struct cmc_string str; \ struct SNAME *h_ = _heap_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_intervalheap, \ - #SNAME, #V, h_, h_->buffer, h_->capacity, h_->size, \ - h_->count, h_->flag, h_->f_val, h_->alloc, \ - h_->callbacks); \ + int n = snprintf(str.s, cmc_string_len, \ + cmc_cmc_string_fmt_intervalheap, #SNAME, #V, h_, \ + h_->buffer, h_->capacity, h_->size, h_->count, \ + h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_heap_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr) \ { \ for (size_t i = 0; i < _heap_->count; i++) \ { \ @@ -766,50 +778,50 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ iter.cursor = target->count - 1; \ \ return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ return true; \ } \ @@ -817,12 +829,12 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->end = true; \ \ return true; \ @@ -831,7 +843,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -842,14 +854,14 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor++; \ \ return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -860,7 +872,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor--; \ \ @@ -868,7 +880,8 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -885,7 +898,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " if (iter->end) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor += steps; \ \ @@ -893,7 +906,8 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -907,7 +921,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " if (steps == 0 || iter->cursor < steps) \ return false; \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor -= steps; \ \ @@ -916,33 +930,34 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->cursor > index) \ - return PFX##_iter_rewind(iter, iter->cursor - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ else if (iter->cursor < index) \ - return PFX##_iter_advance(iter, index - iter->cursor); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->cursor; \ } \ \ - static void PFX##_impl_float_up_max(struct SNAME *_heap_) \ + static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_) \ { \ size_t index = _heap_->size - 1; \ \ @@ -989,7 +1004,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " } \ } \ \ - static void PFX##_impl_float_up_min(struct SNAME *_heap_) \ + static void CMC_(PFX, _impl_float_up_min)(struct SNAME * _heap_) \ { \ size_t index = _heap_->size - 1; \ \ @@ -1017,7 +1032,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " } \ } \ \ - static void PFX##_impl_float_down_max(struct SNAME *_heap_) \ + static void CMC_(PFX, _impl_float_down_max)(struct SNAME * _heap_) \ { \ /* Floats Down from the MinHeap */ \ size_t index = 0; \ @@ -1107,7 +1122,7 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " } \ } \ \ - static void PFX##_impl_float_down_min(struct SNAME *_heap_) \ + static void CMC_(PFX, _impl_float_down_min)(struct SNAME * _heap_) \ { \ /* Floats Down from the MinHeap */ \ size_t index = 0; \ @@ -1171,4 +1186,4 @@ static const char *cmc_string_fmt_intervalheap = "struct %s<%s> " } \ } -#endif /* CMC_INTERVALHEAP_H */ +#endif /* CMC_CMC_INTERVALHEAP_H */ diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index 02d93fc..a5eb3a3 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -25,8 +25,8 @@ * and tail points to the last. */ -#ifndef CMC_LINKEDLIST_H -#define CMC_LINKEDLIST_H +#ifndef CMC_CMC_LINKEDLIST_H +#define CMC_CMC_LINKEDLIST_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -37,194 +37,212 @@ * LinkedList specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " - "at %p { " - "count:%" PRIuMAX ", " - "head:%p, " - "tail:%p, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_linkedlist = "struct %s<%s> " + "at %p { " + "count:%" PRIuMAX ", " + "head:%p, " + "tail:%p, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_LINKEDLIST(PFX, SNAME, V) \ - CMC_GENERATE_LINKEDLIST_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_LINKEDLIST_SOURCE(PFX, SNAME, V) +/** + * Core LinkedList implementation + */ +#define CMC_CMC_LINKEDLIST_CORE(BODY) \ + CMC_CMC_LINKEDLIST_CORE_HEADER(BODY) \ + CMC_CMC_LINKEDLIST_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_LINKEDLIST_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_LINKEDLIST_HEADER(PFX, SNAME, V) +#define CMC_CMC_LINKEDLIST_CORE_HEADER(BODY) \ + CMC_CMC_LINKEDLIST_CORE_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_LINKEDLIST_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_LINKEDLIST_SOURCE(PFX, SNAME, V) +#define CMC_CMC_LINKEDLIST_CORE_SOURCE(BODY) \ + CMC_CMC_LINKEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_LINKEDLIST_HEADER(PFX, SNAME, V) \ - \ - /* Linked List Structure */ \ - struct SNAME \ - { \ - /* First node in the list */ \ - struct SNAME##_node *head; \ - \ - /* Last node in the list */ \ - struct SNAME##_node *tail; \ - \ - /* Current amount of elements in the list */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Doubly-linked list node */ \ - struct SNAME##_node \ - { \ - /* Node's value */ \ - V value; \ - \ - /* Pointer to the next node on the linked list */ \ - struct SNAME##_node *next; \ - \ - /* Pointer to the previous node on the linked list */ \ - struct SNAME##_node *prev; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Linked List Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target Linked List */ \ - struct SNAME *target; \ - \ - /* Cursor's current node */ \ - struct SNAME##_node *cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom(struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_list_); \ - void PFX##_free(struct SNAME *_list_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_push_front(struct SNAME *_list_, V value); \ - bool PFX##_push_at(struct SNAME *_list_, V value, size_t index); \ - bool PFX##_push_back(struct SNAME *_list_, V value); \ - bool PFX##_pop_front(struct SNAME *_list_); \ - bool PFX##_pop_at(struct SNAME *_list_, size_t index); \ - bool PFX##_pop_back(struct SNAME *_list_); \ - /* Element Access */ \ - V PFX##_front(struct SNAME *_list_); \ - V PFX##_get(struct SNAME *_list_, size_t index); \ - V *PFX##_get_ref(struct SNAME *_list_, size_t index); \ - V PFX##_back(struct SNAME *_list_); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_list_, V value); \ - bool PFX##_empty(struct SNAME *_list_); \ - size_t PFX##_count(struct SNAME *_list_); \ - int PFX##_flag(struct SNAME *_list_); \ - /* Collection Utility */ \ - struct SNAME *PFX##_copy_of(struct SNAME *_list_); \ - bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_list_); \ - bool PFX##_print(struct SNAME *_list_, FILE *fptr); \ - \ - /* Node Related Functions */ \ - /* Node Allocation and Deallocation */ \ - struct SNAME##_node *PFX##_new_node(struct SNAME *_list_, V value); \ - void PFX##_free_node(struct SNAME *_list_, struct SNAME##_node *_node_); \ - /* Node Access Relative to a Linked List */ \ - struct SNAME##_node *PFX##_head(struct SNAME *_list_); \ - struct SNAME##_node *PFX##_get_node(struct SNAME *_list_, size_t index); \ - struct SNAME##_node *PFX##_tail(struct SNAME *_list_); \ - /* Input and Output Relative to a Node */ \ - bool PFX##_add_next(struct SNAME *_owner_, struct SNAME##_node *_node_, \ - V value); \ - bool PFX##_add_prev(struct SNAME *_owner_, struct SNAME##_node *_node_, \ - V value); \ - bool PFX##_del_next(struct SNAME *_owner_, struct SNAME##_node *_node_); \ - bool PFX##_del_curr(struct SNAME *_owner_, struct SNAME##_node *_node_); \ - bool PFX##_del_prev(struct SNAME *_owner_, struct SNAME##_node *_node_); \ - /* Node Access Relative to a Linked List Node */ \ - struct SNAME##_node *PFX##_next_node(struct SNAME##_node *_node_); \ - struct SNAME##_node *PFX##_prev_node(struct SNAME##_node *_node_); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); \ - struct SNAME##_node *PFX##_iter_node(struct SNAME##_iter *iter); +#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Linked List Structure */ \ + struct SNAME \ + { \ + /* First node in the list */ \ + struct CMC_DEF_NODE(SNAME) * head; \ + \ + /* Last node in the list */ \ + struct CMC_DEF_NODE(SNAME) * tail; \ + \ + /* Current amount of elements in the list */ \ + size_t count; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Doubly-linked list node */ \ + struct CMC_DEF_NODE(SNAME) \ + { \ + /* Node's value */ \ + V value; \ + \ + /* Pointer to the next node on the linked list */ \ + struct CMC_DEF_NODE(SNAME) * next; \ + \ + /* Pointer to the previous node on the linked list */ \ + struct CMC_DEF_NODE(SNAME) * prev; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Linked List Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target Linked List */ \ + struct SNAME *target; \ + \ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ + V CMC_(PFX, _back)(struct SNAME * _list_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \ + \ + /* Node Related Functions */ \ + /* Node Allocation and Deallocation */ \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \ + void CMC_(PFX, _free_node)(struct SNAME * _list_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + /* Node Access Relative to a Linked List */ \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \ + /* Input and Output Relative to a Node */ \ + bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value); \ + bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value); \ + bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + /* Node Access Relative to a Linked List Node */ \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_LINKEDLIST_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ /* None */ \ \ - struct SNAME *PFX##_new(struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ if (!f_val) \ return NULL; \ @@ -239,7 +257,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _list_->count = 0; \ _list_->head = NULL; \ _list_->tail = NULL; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ _list_->f_val = f_val; \ _list_->alloc = alloc; \ _list_->callbacks = NULL; \ @@ -247,9 +265,9 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return _list_; \ } \ \ - struct SNAME *PFX##_new_custom(struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!f_val) \ return NULL; \ @@ -265,7 +283,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _list_->count = 0; \ _list_->head = NULL; \ _list_->tail = NULL; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ _list_->f_val = f_val; \ _list_->alloc = alloc; \ _list_->callbacks = callbacks; \ @@ -273,9 +291,9 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return _list_; \ } \ \ - void PFX##_clear(struct SNAME *_list_) \ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ { \ - struct SNAME##_node *scan = _list_->head; \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ \ while (_list_->head != NULL) \ { \ @@ -294,18 +312,19 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _list_->count = 0; \ _list_->head = NULL; \ _list_->tail = NULL; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_list_) \ + void CMC_(PFX, _free)(struct SNAME * _list_) \ { \ - PFX##_clear(_list_); \ + CMC_(PFX, _clear)(_list_); \ \ _list_->alloc->free(_list_); \ } \ \ - void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ @@ -314,17 +333,18 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " \ _list_->callbacks = callbacks; \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_push_front(struct SNAME *_list_, V value) \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ { \ - struct SNAME##_node *_node_ = PFX##_new_node(_list_, value); \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ \ if (!_node_) \ return false; \ \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ _list_->head = _node_; \ _list_->tail = _node_; \ @@ -337,7 +357,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " } \ \ _list_->count++; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -345,29 +365,31 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - bool PFX##_push_at(struct SNAME *_list_, V value, size_t index) \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ { \ if (index > _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return false; \ } \ \ if (index == 0) \ { \ - return PFX##_push_front(_list_, value); \ + return CMC_(PFX, _push_front)(_list_, value); \ } \ else if (index == _list_->count) \ { \ - return PFX##_push_back(_list_, value); \ + return CMC_(PFX, _push_back)(_list_, value); \ } \ \ - struct SNAME##_node *_node_ = PFX##_new_node(_list_, value); \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ \ if (!_node_) \ return false; \ \ - struct SNAME##_node *scan = PFX##_get_node(_list_, index - 1); \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index - 1); \ \ _node_->next = scan->next; \ _node_->prev = scan; \ @@ -375,7 +397,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _node_->prev->next = _node_; \ \ _list_->count++; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -383,14 +405,15 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - bool PFX##_push_back(struct SNAME *_list_, V value) \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ { \ - struct SNAME##_node *_node_ = PFX##_new_node(_list_, value); \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ \ if (!_node_) \ return false; \ \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ _list_->head = _node_; \ _list_->tail = _node_; \ @@ -403,7 +426,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " } \ \ _list_->count++; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -411,15 +434,15 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop_front(struct SNAME *_list_) \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *_node_ = _list_->head; \ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \ _list_->head = _list_->head->next; \ \ _list_->alloc->free(_node_); \ @@ -430,7 +453,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _list_->head->prev = NULL; \ \ _list_->count--; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -438,30 +461,31 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop_at(struct SNAME *_list_, size_t index) \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return false; \ } \ \ if (index == 0) \ { \ - return PFX##_pop_front(_list_); \ + return CMC_(PFX, _pop_front)(_list_); \ } \ else if (index == _list_->count - 1) \ { \ - return PFX##_pop_back(_list_); \ + return CMC_(PFX, _pop_back)(_list_); \ } \ \ - struct SNAME##_node *_node_ = PFX##_get_node(_list_, index); \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _get_node)(_list_, index); \ \ if (!_node_) \ return false; \ @@ -472,7 +496,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _list_->alloc->free(_node_); \ \ _list_->count--; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -480,15 +504,15 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop_back(struct SNAME *_list_) \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *_node_ = _list_->tail; \ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \ _list_->tail = _list_->tail->prev; \ \ _list_->alloc->free(_node_); \ @@ -499,7 +523,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _list_->tail->next = NULL; \ \ _list_->count--; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -507,15 +531,15 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - V PFX##_front(struct SNAME *_list_) \ + V CMC_(PFX, _front)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -523,21 +547,22 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return _list_->head->value; \ } \ \ - V PFX##_get(struct SNAME *_list_, size_t index) \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return (V){ 0 }; \ } \ \ - struct SNAME##_node *scan = PFX##_get_node(_list_, index); \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index); \ \ if (scan == NULL) \ return (V){ 0 }; \ @@ -548,21 +573,22 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return scan->value; \ } \ \ - V *PFX##_get_ref(struct SNAME *_list_, size_t index) \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return NULL; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return NULL; \ } \ \ - struct SNAME##_node *scan = PFX##_get_node(_list_, index); \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index); \ \ if (scan == NULL) \ return NULL; \ @@ -573,15 +599,15 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return &(scan->value); \ } \ \ - V PFX##_back(struct SNAME *_list_) \ + V CMC_(PFX, _back)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -589,13 +615,13 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return _list_->tail->value; \ } \ \ - bool PFX##_contains(struct SNAME *_list_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ { \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ bool result = false; \ \ - struct SNAME##_node *scan = _list_->head; \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ \ while (scan != NULL) \ { \ @@ -614,42 +640,42 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_list_) \ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ { \ return _list_->count == 0; \ } \ \ - size_t PFX##_count(struct SNAME *_list_) \ + size_t CMC_(PFX, _count)(struct SNAME * _list_) \ { \ return _list_->count; \ } \ \ - int PFX##_flag(struct SNAME *_list_) \ + int CMC_(PFX, _flag)(struct SNAME * _list_) \ { \ return _list_->flag; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_list_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ { \ - struct SNAME *result = \ - PFX##_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks); \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _list_->f_val, _list_->alloc, _list_->callbacks); \ \ if (!result) \ return NULL; \ \ - struct SNAME##_node *scan = _list_->head; \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ \ while (scan != NULL) \ { \ /* This allocation should never fail since it might not be */ \ /* possible to recover from it. That is why it isn't checked */ \ - struct SNAME##_node *new_node; \ + struct CMC_DEF_NODE(SNAME) * new_node; \ \ if (_list_->f_val->cpy) \ - new_node = \ - PFX##_new_node(_list_, _list_->f_val->cpy(scan->value)); \ + new_node = CMC_(PFX, _new_node)( \ + _list_, _list_->f_val->cpy(scan->value)); \ else \ - new_node = PFX##_new_node(_list_, scan->value); \ + new_node = CMC_(PFX, _new_node)(_list_, scan->value); \ \ if (!result->head) \ { \ @@ -668,21 +694,21 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " \ result->count = _list_->count; \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ { \ - _list1_->flag = cmc_flags.OK; \ - _list2_->flag = cmc_flags.OK; \ + _list1_->flag = CMC_FLAG_OK; \ + _list2_->flag = CMC_FLAG_OK; \ \ if (_list1_->count != _list2_->count) \ return false; \ \ - struct SNAME##_node *scan1 = _list1_->head; \ - struct SNAME##_node *scan2 = _list2_->head; \ + struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \ + struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \ \ while (scan1 != NULL && scan2 != NULL) \ { \ @@ -696,21 +722,21 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_list_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ { \ struct cmc_string str; \ struct SNAME *l_ = _list_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_linkedlist, \ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_linkedlist, \ #SNAME, #V, l_, l_->count, l_->head, l_->tail, \ l_->flag, l_->f_val, l_->alloc, l_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_list_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ { \ - struct SNAME##_node *scan = _list_->head; \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ \ while (scan != NULL) \ { \ @@ -723,14 +749,15 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_node *PFX##_new_node(struct SNAME *_list_, V value) \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \ { \ - struct SNAME##_node *_node_ = \ - _list_->alloc->malloc(sizeof(struct SNAME##_node)); \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ \ if (!_node_) \ { \ - _list_->flag = cmc_flags.ALLOC; \ + _list_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ @@ -741,31 +768,33 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return _node_; \ } \ \ - void PFX##_free_node(struct SNAME *_list_, struct SNAME##_node *_node_) \ + void CMC_(PFX, _free_node)(struct SNAME * _list_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ { \ _list_->alloc->free(_node_); \ } \ \ - struct SNAME##_node *PFX##_head(struct SNAME *_list_) \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \ { \ return _list_->head; \ } \ \ - struct SNAME##_node *PFX##_get_node(struct SNAME *_list_, size_t index) \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return NULL; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return NULL; \ } \ \ - struct SNAME##_node *_node_ = NULL; \ + struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \ \ if (index <= _list_->count / 2) \ { \ @@ -784,20 +813,21 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " } \ } \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ return _node_; \ } \ \ - struct SNAME##_node *PFX##_tail(struct SNAME *_list_) \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \ { \ return _list_->tail; \ } \ \ - bool PFX##_add_next(struct SNAME *_owner_, struct SNAME##_node *_node_, \ - V value) \ + bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value) \ { \ - struct SNAME##_node *new_node = PFX##_new_node(_owner_, value); \ + struct CMC_DEF_NODE(SNAME) *new_node = \ + CMC_(PFX, _new_node)(_owner_, value); \ \ if (!new_node) \ return false; \ @@ -813,15 +843,16 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _node_->next = new_node; \ \ _owner_->count++; \ - _owner_->flag = cmc_flags.OK; \ + _owner_->flag = CMC_FLAG_OK; \ \ return true; \ } \ \ - bool PFX##_add_prev(struct SNAME *_owner_, struct SNAME##_node *_node_, \ - V value) \ + bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value) \ { \ - struct SNAME##_node *new_node = PFX##_new_node(_owner_, value); \ + struct CMC_DEF_NODE(SNAME) *new_node = \ + CMC_(PFX, _new_node)(_owner_, value); \ \ if (!new_node) \ return false; \ @@ -837,20 +868,21 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _node_->prev = new_node; \ \ _owner_->count++; \ - _owner_->flag = cmc_flags.OK; \ + _owner_->flag = CMC_FLAG_OK; \ \ return true; \ } \ \ - bool PFX##_del_next(struct SNAME *_owner_, struct SNAME##_node *_node_) \ + bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ { \ if (_node_->next == NULL) \ { \ - _owner_->flag = cmc_flags.INVALID; \ + _owner_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ - struct SNAME##_node *tmp = _node_->next; \ + struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \ \ _node_->next = _node_->next->next; \ \ @@ -862,12 +894,13 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _owner_->alloc->free(tmp); \ \ _owner_->count--; \ - _owner_->flag = cmc_flags.OK; \ + _owner_->flag = CMC_FLAG_OK; \ \ return true; \ } \ \ - bool PFX##_del_curr(struct SNAME *_owner_, struct SNAME##_node *_node_) \ + bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ { \ if (_node_->prev != NULL) \ _node_->prev->next = _node_->next; \ @@ -882,20 +915,21 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _owner_->alloc->free(_node_); \ \ _owner_->count--; \ - _owner_->flag = cmc_flags.OK; \ + _owner_->flag = CMC_FLAG_OK; \ \ return true; \ } \ \ - bool PFX##_del_prev(struct SNAME *_owner_, struct SNAME##_node *_node_) \ + bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ { \ if (_node_->prev == NULL) \ { \ - _owner_->flag = cmc_flags.INVALID; \ + _owner_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ - struct SNAME##_node *tmp = _node_->prev; \ + struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \ \ _node_->prev = _node_->prev->prev; \ \ @@ -907,68 +941,70 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " _owner_->alloc->free(tmp); \ \ _owner_->count--; \ - _owner_->flag = cmc_flags.OK; \ + _owner_->flag = CMC_FLAG_OK; \ \ return true; \ } \ \ - struct SNAME##_node *PFX##_next_node(struct SNAME##_node *_node_) \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ { \ return _node_->next; \ } \ \ - struct SNAME##_node *PFX##_prev_node(struct SNAME##_node *_node_) \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ { \ return _node_->prev; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = target->head; \ iter.index = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = target->tail; \ iter.index = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ iter.index = target->count - 1; \ \ return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->target->head; \ iter->index = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ return true; \ } \ @@ -976,13 +1012,13 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->target->tail; \ iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->end = true; \ \ return true; \ @@ -991,7 +1027,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -1002,7 +1038,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor = iter->cursor->next; \ iter->index++; \ @@ -1010,7 +1046,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -1021,7 +1057,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor = iter->cursor->prev; \ iter->index--; \ @@ -1030,7 +1066,8 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -1044,7 +1081,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " if (steps == 0 || iter->index + steps >= iter->target->count) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->index += steps; \ \ @@ -1055,7 +1092,8 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -1069,7 +1107,7 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " if (steps == 0 || iter->index < steps) \ return false; \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->index -= steps; \ \ @@ -1081,43 +1119,45 @@ static const char *cmc_string_fmt_linkedlist = "struct %s<%s> " \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->cursor->value; \ } \ \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return NULL; \ \ return &(iter->cursor->value); \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->index; \ } \ \ - struct SNAME##_node *PFX##_iter_node(struct SNAME##_iter *iter) \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->cursor; \ } -#endif /* CMC_LINKEDLIST_H */ +#endif /* CMC_CMC_LINKEDLIST_H */ diff --git a/src/cmc/list.h b/src/cmc/list.h index aa7ff78..a8fc1c9 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -40,8 +40,8 @@ * list. */ -#ifndef CMC_LIST_H -#define CMC_LIST_H +#ifndef CMC_CMC_LIST_H +#define CMC_CMC_LIST_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -52,170 +52,185 @@ * List specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_list = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_LIST(PFX, SNAME, V) \ - CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) +/** + * Core List implementation + */ +#define CMC_CMC_LIST_CORE(BODY) \ + CMC_CMC_LIST_CORE_HEADER(BODY) \ + CMC_CMC_LIST_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_LIST_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) +#define CMC_CMC_LIST_CORE_HEADER(BODY) \ + CMC_CMC_LIST_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_LIST_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) +#define CMC_CMC_LIST_CORE_SOURCE(BODY) \ + CMC_CMC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) \ - \ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* List Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target list */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_list_); \ - void PFX##_free(struct SNAME *_list_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_push_front(struct SNAME *_list_, V value); \ - bool PFX##_push_at(struct SNAME *_list_, V value, size_t index); \ - bool PFX##_push_back(struct SNAME *_list_, V value); \ - bool PFX##_pop_front(struct SNAME *_list_); \ - bool PFX##_pop_at(struct SNAME *_list_, size_t index); \ - bool PFX##_pop_back(struct SNAME *_list_); \ - /* Collection Sequence Input and Output */ \ - bool PFX##_seq_push_front(struct SNAME *_list_, V *values, size_t size); \ - bool PFX##_seq_push_at(struct SNAME *_list_, V *values, size_t size, \ - size_t index); \ - bool PFX##_seq_push_back(struct SNAME *_list_, V *values, size_t size); \ - bool PFX##_seq_pop_at(struct SNAME *_list_, size_t from, size_t to); \ - struct SNAME *PFX##_seq_sublist(struct SNAME *_list_, size_t from, \ - size_t to); \ - /* Element Access */ \ - V PFX##_front(struct SNAME *_list_); \ - V PFX##_get(struct SNAME *_list_, size_t index); \ - V *PFX##_get_ref(struct SNAME *_list_, size_t index); \ - V PFX##_back(struct SNAME *_list_); \ - size_t PFX##_index_of(struct SNAME *_list_, V value, bool from_start); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_list_, V value); \ - bool PFX##_empty(struct SNAME *_list_); \ - bool PFX##_full(struct SNAME *_list_); \ - size_t PFX##_count(struct SNAME *_list_); \ - bool PFX##_fits(struct SNAME *_list_, size_t size); \ - size_t PFX##_capacity(struct SNAME *_list_); \ - int PFX##_flag(struct SNAME *_list_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_list_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_list_); \ - bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_list_); \ - bool PFX##_print(struct SNAME *_list_, FILE *fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* List Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* List Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target list */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ + /* Collection Sequence Input and Output */ \ + bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ + size_t size); \ + bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ + size_t size, size_t index); \ + bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ + size_t size); \ + bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, \ + size_t to); \ + struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ + size_t to); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ + V CMC_(PFX, _back)(struct SNAME * _list_); \ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ + bool from_start); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + bool CMC_(PFX, _full)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_LIST_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ /* None */ \ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -237,7 +252,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " \ _list_->capacity = capacity; \ _list_->count = 0; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ _list_->f_val = f_val; \ _list_->alloc = alloc; \ _list_->callbacks = NULL; \ @@ -245,9 +260,9 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return _list_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ if (capacity < 1) \ return NULL; \ @@ -273,7 +288,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " \ _list_->capacity = capacity; \ _list_->count = 0; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ _list_->f_val = f_val; \ _list_->alloc = alloc; \ _list_->callbacks = callbacks; \ @@ -281,7 +296,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return _list_; \ } \ \ - void PFX##_clear(struct SNAME *_list_) \ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ { \ if (_list_->f_val->free) \ { \ @@ -292,10 +307,10 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ \ _list_->count = 0; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_list_) \ + void CMC_(PFX, _free)(struct SNAME * _list_) \ { \ if (_list_->f_val->free) \ { \ @@ -307,8 +322,9 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " _list_->alloc->free(_list_); \ } \ \ - void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ @@ -317,18 +333,18 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " \ _list_->callbacks = callbacks; \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_push_front(struct SNAME *_list_, V value) \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ { \ - if (PFX##_full(_list_)) \ + if (CMC_(PFX, _full)(_list_)) \ { \ - if (!PFX##_resize(_list_, _list_->count * 2)) \ + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ return false; \ } \ \ - if (!PFX##_empty(_list_)) \ + if (!CMC_(PFX, _empty)(_list_)) \ { \ memmove(_list_->buffer + 1, _list_->buffer, \ _list_->count * sizeof(V)); \ @@ -337,7 +353,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " _list_->buffer[0] = value; \ \ _list_->count++; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -345,17 +361,17 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_push_at(struct SNAME *_list_, V value, size_t index) \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ { \ if (index > _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return false; \ } \ \ - if (PFX##_full(_list_)) \ + if (CMC_(PFX, _full)(_list_)) \ { \ - if (!PFX##_resize(_list_, _list_->count * 2)) \ + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ return false; \ } \ \ @@ -364,7 +380,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " \ _list_->buffer[index] = value; \ _list_->count++; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -372,16 +388,16 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_push_back(struct SNAME *_list_, V value) \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ { \ - if (PFX##_full(_list_)) \ + if (CMC_(PFX, _full)(_list_)) \ { \ - if (!PFX##_resize(_list_, _list_->count * 2)) \ + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ return false; \ } \ \ _list_->buffer[_list_->count++] = value; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -389,11 +405,11 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop_front(struct SNAME *_list_) \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -401,7 +417,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " (_list_->count - 1) * sizeof(V)); \ \ _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -409,17 +425,17 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop_at(struct SNAME *_list_, size_t index) \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return false; \ } \ \ @@ -427,7 +443,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " (_list_->count - index - 1) * sizeof(V)); \ \ _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -435,13 +451,13 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop_back(struct SNAME *_list_) \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ return false; \ \ _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -449,17 +465,18 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_seq_push_front(struct SNAME *_list_, V *values, size_t size) \ + bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ + size_t size) \ { \ if (size == 0) \ { \ - _list_->flag = cmc_flags.INVALID; \ + _list_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ - if (!PFX##_fits(_list_, size)) \ + if (!CMC_(PFX, _fits)(_list_, size)) \ { \ - if (!PFX##_resize(_list_, _list_->count + size)) \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ return false; \ } \ \ @@ -469,7 +486,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " memcpy(_list_->buffer, values, size * sizeof(V)); \ \ _list_->count += size; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -477,29 +494,29 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_seq_push_at(struct SNAME *_list_, V *values, size_t size, \ - size_t index) \ + bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ + size_t size, size_t index) \ { \ if (size == 0) \ { \ - _list_->flag = cmc_flags.INVALID; \ + _list_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ if (index > _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return false; \ } \ \ if (index == 0) \ - return PFX##_seq_push_front(_list_, values, size); \ + return CMC_(PFX, _seq_push_front)(_list_, values, size); \ else if (index == _list_->count) \ - return PFX##_seq_push_back(_list_, values, size); \ + return CMC_(PFX, _seq_push_back)(_list_, values, size); \ \ - if (!PFX##_fits(_list_, size)) \ + if (!CMC_(PFX, _fits)(_list_, size)) \ { \ - if (!PFX##_resize(_list_, _list_->count + size)) \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ return false; \ } \ \ @@ -509,7 +526,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " memcpy(_list_->buffer + index, values, size * sizeof(V)); \ \ _list_->count += size; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -517,24 +534,25 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_seq_push_back(struct SNAME *_list_, V *values, size_t size) \ + bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ + size_t size) \ { \ if (size == 0) \ { \ - _list_->flag = cmc_flags.INVALID; \ + _list_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ - if (!PFX##_fits(_list_, size)) \ + if (!CMC_(PFX, _fits)(_list_, size)) \ { \ - if (!PFX##_resize(_list_, _list_->count + size)) \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ return false; \ } \ \ memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \ \ _list_->count += size; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -542,17 +560,17 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool PFX##_seq_pop_at(struct SNAME *_list_, size_t from, size_t to) \ + bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \ { \ if (from > to) \ { \ - _list_->flag = cmc_flags.INVALID; \ + _list_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ if (to >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return false; \ } \ \ @@ -565,7 +583,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " length * sizeof(V)); \ \ _list_->count -= to - from + 1; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -573,29 +591,29 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_seq_sublist(struct SNAME *_list_, size_t from, \ - size_t to) \ + struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ + size_t to) \ { \ if (from > to) \ { \ - _list_->flag = cmc_flags.INVALID; \ + _list_->flag = CMC_FLAG_INVALID; \ return NULL; \ } \ \ if (to >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return NULL; \ } \ \ size_t length = to - from + 1; \ \ - struct SNAME *result = PFX##_new_custom( \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ length, _list_->f_val, _list_->alloc, _list_->callbacks); \ \ if (!result) \ { \ - _list_->flag = cmc_flags.ALLOC; \ + _list_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ @@ -610,7 +628,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " _list_->count -= length; \ result->count = length; \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -618,15 +636,15 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return result; \ } \ \ - V PFX##_front(struct SNAME *_list_) \ + V CMC_(PFX, _front)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -634,21 +652,21 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return _list_->buffer[0]; \ } \ \ - V PFX##_get(struct SNAME *_list_, size_t index) \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return (V){ 0 }; \ } \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -656,21 +674,21 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return _list_->buffer[index]; \ } \ \ - V *PFX##_get_ref(struct SNAME *_list_, size_t index) \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return NULL; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return NULL; \ } \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -678,15 +696,15 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return &(_list_->buffer[index]); \ } \ \ - V PFX##_back(struct SNAME *_list_) \ + V CMC_(PFX, _back)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -694,9 +712,10 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return _list_->buffer[_list_->count - 1]; \ } \ \ - size_t PFX##_index_of(struct SNAME *_list_, V value, bool from_start) \ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ + bool from_start) \ { \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ size_t result = _list_->count; \ \ @@ -729,9 +748,9 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return result; \ } \ \ - bool PFX##_contains(struct SNAME *_list_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ { \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ bool result = false; \ \ @@ -750,46 +769,46 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_list_) \ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ { \ return _list_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_list_) \ + bool CMC_(PFX, _full)(struct SNAME * _list_) \ { \ return _list_->count >= _list_->capacity; \ } \ \ - size_t PFX##_count(struct SNAME *_list_) \ + size_t CMC_(PFX, _count)(struct SNAME * _list_) \ { \ return _list_->count; \ } \ \ - bool PFX##_fits(struct SNAME *_list_, size_t size) \ + bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size) \ { \ return _list_->count + size <= _list_->capacity; \ } \ \ - size_t PFX##_capacity(struct SNAME *_list_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ { \ return _list_->capacity; \ } \ \ - int PFX##_flag(struct SNAME *_list_) \ + int CMC_(PFX, _flag)(struct SNAME * _list_) \ { \ return _list_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_list_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \ { \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->capacity == capacity) \ return true; \ \ if (capacity < _list_->count) \ { \ - _list_->flag = cmc_flags.INVALID; \ + _list_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ @@ -798,7 +817,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " \ if (!new_buffer) \ { \ - _list_->flag = cmc_flags.ALLOC; \ + _list_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -813,15 +832,15 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_list_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ { \ struct SNAME *result = \ - PFX##_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, \ - _list_->callbacks); \ + CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, \ + _list_->alloc, _list_->callbacks); \ \ if (!result) \ { \ - _list_->flag = cmc_flags.ALLOC; \ + _list_->flag = CMC_FLAG_ALLOC; \ return NULL; \ } \ \ @@ -835,15 +854,15 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " \ result->count = _list_->count; \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ { \ - _list1_->flag = cmc_flags.OK; \ - _list2_->flag = cmc_flags.OK; \ + _list1_->flag = CMC_FLAG_OK; \ + _list2_->flag = CMC_FLAG_OK; \ \ if (_list1_->count != _list2_->count) \ return false; \ @@ -858,19 +877,19 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_list_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ { \ struct cmc_string str; \ struct SNAME *l_ = _list_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_list, #SNAME, \ - #V, l_, l_->buffer, l_->capacity, l_->count, \ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_list, \ + #SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \ l_->flag, l_->f_val, l_->alloc, l_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_list_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ { \ for (size_t i = 0; i < _list_->count; i++) \ { \ @@ -881,50 +900,50 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ iter.cursor = target->count - 1; \ \ return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ return true; \ } \ @@ -932,11 +951,11 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->cursor = iter->target->count - 1; \ iter->end = true; \ \ @@ -946,7 +965,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -957,14 +976,14 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor++; \ \ return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -975,7 +994,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor--; \ \ @@ -983,7 +1002,8 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -997,7 +1017,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " if (steps == 0 || iter->cursor + steps >= iter->target->count) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor += steps; \ \ @@ -1005,7 +1025,8 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -1019,7 +1040,7 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " if (steps == 0 || iter->cursor < steps) \ return false; \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor -= steps; \ \ @@ -1028,38 +1049,39 @@ static const char *cmc_string_fmt_list = "struct %s<%s> " \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->cursor > index) \ - return PFX##_iter_rewind(iter, iter->cursor - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ else if (iter->cursor < index) \ - return PFX##_iter_advance(iter, index - iter->cursor); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor]; \ } \ \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return NULL; \ \ return &(iter->target->buffer[iter->cursor]); \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->cursor; \ } -#endif /* CMC_LIST_H */ +#endif /* CMC_CMC_LIST_H */ diff --git a/src/cmc/queue.h b/src/cmc/queue.h index 10f3fb0..4f2148f 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -40,8 +40,8 @@ * the resource. */ -#ifndef CMC_QUEUE_H -#define CMC_QUEUE_H +#ifndef CMC_CMC_QUEUE_H +#define CMC_CMC_QUEUE_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -52,164 +52,175 @@ * Queue specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_queue = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "front:%" PRIuMAX ", " - "back:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_queue = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "front:%" PRIuMAX ", " + "back:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_QUEUE(PFX, SNAME, V) \ - CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V) +/** + * Core Queue implementation + */ +#define CMC_CMC_QUEUE_CORE(BODY) \ + CMC_CMC_QUEUE_CORE_HEADER(BODY) \ + CMC_CMC_QUEUE_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_QUEUE_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) +#define CMC_CMC_QUEUE_CORE_HEADER(BODY) \ + CMC_CMC_QUEUE_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_QUEUE_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V) +#define CMC_CMC_QUEUE_CORE_SOURCE(BODY) \ + CMC_CMC_QUEUE_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) \ - \ - /* Queue Structure */ \ - struct SNAME \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ - \ - /* Current circular array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Index representing the front of the queue */ \ - size_t front; \ - \ - /* Index representing the back of the queue */ \ - size_t back; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Queue Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target queue */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_queue_); \ - void PFX##_free(struct SNAME *_queue_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_queue_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_enqueue(struct SNAME *_queue_, V value); \ - bool PFX##_dequeue(struct SNAME *_queue_); \ - /* Element Access */ \ - V PFX##_peek(struct SNAME *_queue_); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_queue_, V value); \ - bool PFX##_empty(struct SNAME *_queue_); \ - bool PFX##_full(struct SNAME *_queue_); \ - size_t PFX##_count(struct SNAME *_queue_); \ - size_t PFX##_capacity(struct SNAME *_queue_); \ - int PFX##_flag(struct SNAME *_queue_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_queue_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_queue_); \ - bool PFX##_equals(struct SNAME *_queue1_, struct SNAME *_queue2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_queue_); \ - bool PFX##_print(struct SNAME *_queue_, FILE *fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_QUEUE_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Queue Structure */ \ + struct SNAME \ + { \ + /* Dynamic circular array of elements */ \ + V *buffer; \ + \ + /* Current circular array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Index representing the front of the queue */ \ + size_t front; \ + \ + /* Index representing the back of the queue */ \ + size_t back; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Queue Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target queue */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _queue_); \ + void CMC_(PFX, _free)(struct SNAME * _queue_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _queue_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value); \ + bool CMC_(PFX, _dequeue)(struct SNAME * _queue_); \ + /* Element Access */ \ + V CMC_(PFX, _peek)(struct SNAME * _queue_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _queue_); \ + bool CMC_(PFX, _full)(struct SNAME * _queue_); \ + size_t CMC_(PFX, _count)(struct SNAME * _queue_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _queue_); \ + int CMC_(PFX, _flag)(struct SNAME * _queue_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_); \ + bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _queue_); \ + bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_QUEUE_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ /* None */ \ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -236,7 +247,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " _queue_->count = 0; \ _queue_->front = 0; \ _queue_->back = 0; \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ _queue_->f_val = f_val; \ _queue_->alloc = alloc; \ _queue_->callbacks = NULL; \ @@ -244,9 +255,9 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return _queue_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ if (capacity < 1) \ return NULL; \ @@ -274,7 +285,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " _queue_->count = 0; \ _queue_->front = 0; \ _queue_->back = 0; \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ _queue_->f_val = f_val; \ _queue_->alloc = alloc; \ _queue_->callbacks = callbacks; \ @@ -282,7 +293,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return _queue_; \ } \ \ - void PFX##_clear(struct SNAME *_queue_) \ + void CMC_(PFX, _clear)(struct SNAME * _queue_) \ { \ if (_queue_->f_val->free) \ { \ @@ -299,10 +310,10 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " _queue_->count = 0; \ _queue_->front = 0; \ _queue_->back = 0; \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_queue_) \ + void CMC_(PFX, _free)(struct SNAME * _queue_) \ { \ if (_queue_->f_val->free) \ { \ @@ -318,8 +329,9 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " _queue_->alloc->free(_queue_); \ } \ \ - void PFX##_customize(struct SNAME *_queue_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _queue_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _queue_->alloc = &cmc_alloc_node_default; \ @@ -328,14 +340,14 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " \ _queue_->callbacks = callbacks; \ \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_enqueue(struct SNAME *_queue_, V value) \ + bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value) \ { \ - if (PFX##_full(_queue_)) \ + if (CMC_(PFX, _full)(_queue_)) \ { \ - if (!PFX##_resize(_queue_, _queue_->capacity * 2)) \ + if (!CMC_(PFX, _resize)(_queue_, _queue_->capacity * 2)) \ return false; \ } \ \ @@ -344,7 +356,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " _queue_->back = \ (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \ _queue_->count++; \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ \ if (_queue_->callbacks && _queue_->callbacks->create) \ _queue_->callbacks->create(); \ @@ -352,11 +364,11 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return true; \ } \ \ - bool PFX##_dequeue(struct SNAME *_queue_) \ + bool CMC_(PFX, _dequeue)(struct SNAME * _queue_) \ { \ - if (PFX##_empty(_queue_)) \ + if (CMC_(PFX, _empty)(_queue_)) \ { \ - _queue_->flag = cmc_flags.EMPTY; \ + _queue_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ @@ -366,7 +378,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " ? 0 \ : _queue_->front + 1; \ _queue_->count--; \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ \ if (_queue_->callbacks && _queue_->callbacks->delete) \ _queue_->callbacks->delete (); \ @@ -374,15 +386,15 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return true; \ } \ \ - V PFX##_peek(struct SNAME *_queue_) \ + V CMC_(PFX, _peek)(struct SNAME * _queue_) \ { \ - if (PFX##_empty(_queue_)) \ + if (CMC_(PFX, _empty)(_queue_)) \ { \ - _queue_->flag = cmc_flags.EMPTY; \ + _queue_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ \ if (_queue_->callbacks && _queue_->callbacks->read) \ _queue_->callbacks->read(); \ @@ -390,9 +402,9 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return _queue_->buffer[_queue_->front]; \ } \ \ - bool PFX##_contains(struct SNAME *_queue_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value) \ { \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ \ bool result = false; \ \ @@ -413,39 +425,39 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_queue_) \ + bool CMC_(PFX, _empty)(struct SNAME * _queue_) \ { \ return _queue_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_queue_) \ + bool CMC_(PFX, _full)(struct SNAME * _queue_) \ { \ return _queue_->count >= _queue_->capacity; \ } \ \ - size_t PFX##_count(struct SNAME *_queue_) \ + size_t CMC_(PFX, _count)(struct SNAME * _queue_) \ { \ return _queue_->count; \ } \ \ - size_t PFX##_capacity(struct SNAME *_queue_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _queue_) \ { \ return _queue_->capacity; \ } \ \ - int PFX##_flag(struct SNAME *_queue_) \ + int CMC_(PFX, _flag)(struct SNAME * _queue_) \ { \ return _queue_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_queue_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity) \ { \ if (_queue_->capacity == capacity) \ goto success; \ \ if (capacity < _queue_->count) \ { \ - _queue_->flag = cmc_flags.INVALID; \ + _queue_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ @@ -453,7 +465,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " \ if (!new_buffer) \ { \ - _queue_->flag = cmc_flags.ALLOC; \ + _queue_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -473,7 +485,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " \ success: \ \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ \ if (_queue_->callbacks && _queue_->callbacks->resize) \ _queue_->callbacks->resize(); \ @@ -481,15 +493,15 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_queue_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_) \ { \ struct SNAME *result = \ - PFX##_new_custom(_queue_->capacity, _queue_->f_val, \ - _queue_->alloc, _queue_->callbacks); \ + CMC_(PFX, _new_custom)(_queue_->capacity, _queue_->f_val, \ + _queue_->alloc, _queue_->callbacks); \ \ if (!result) \ { \ - _queue_->flag = cmc_flags.ERROR; \ + _queue_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ @@ -516,15 +528,15 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " result->front = 0; \ result->back = _queue_->count; \ \ - _queue_->flag = cmc_flags.OK; \ + _queue_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_queue1_, struct SNAME *_queue2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_) \ { \ - _queue1_->flag = cmc_flags.OK; \ - _queue2_->flag = cmc_flags.OK; \ + _queue1_->flag = CMC_FLAG_OK; \ + _queue2_->flag = CMC_FLAG_OK; \ \ if (_queue1_->count != _queue2_->count) \ return false; \ @@ -544,20 +556,20 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_queue_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _queue_) \ { \ struct cmc_string str; \ struct SNAME *q_ = _queue_; \ \ int n = \ - snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, #SNAME, #V, \ - q_, q_->buffer, q_->capacity, q_->count, q_->front, \ + snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_queue, #SNAME, \ + #V, q_, q_->buffer, q_->capacity, q_->count, q_->front, \ q_->back, q_->flag, q_->f_val, q_->alloc, q_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_queue_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr) \ { \ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ { \ @@ -570,26 +582,26 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = target->front; \ iter.index = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ if (iter.target->back == 0) \ iter.cursor = iter.target->capacity - 1; \ @@ -604,25 +616,25 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " iter.index = 0; \ } \ \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->target->front; \ iter->index = 0; \ @@ -635,9 +647,9 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ if (iter->target->back == 0) \ iter->cursor = iter->target->capacity - 1; \ @@ -655,7 +667,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -666,7 +678,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ iter->index++; \ @@ -674,7 +686,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -685,7 +697,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \ : iter->cursor - 1; \ @@ -695,7 +707,8 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -709,7 +722,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " if (steps == 0 || iter->index + steps >= iter->target->count) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->index += steps; \ iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ @@ -718,7 +731,8 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -732,7 +746,7 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " if (steps == 0 || iter->index < steps) \ return false; \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->index -= steps; \ \ @@ -747,38 +761,39 @@ static const char *cmc_string_fmt_queue = "struct %s<%s> " \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor]; \ } \ \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return NULL; \ \ return &(iter->target->buffer[iter->cursor]); \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->index; \ } -#endif /* CMC_QUEUE_H */ +#endif /* CMC_CMC_QUEUE_H */ diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h index 47edbc7..eddf1df 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc/sortedlist.h @@ -19,8 +19,8 @@ * variation of quick sort that uses insertion sort for small partitions. */ -#ifndef CMC_SORTEDLIST_H -#define CMC_SORTEDLIST_H +#ifndef CMC_CMC_SORTEDLIST_H +#define CMC_CMC_SORTEDLIST_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -31,167 +31,179 @@ * SortedList specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "is_sorted:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "is_sorted:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_SORTEDLIST(PFX, SNAME, V) \ - CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_SORTEDLIST_SOURCE(PFX, SNAME, V) +/** + * Core SortedList implementation + */ +#define CMC_CMC_SORTEDLIST_CORE(BODY) \ + CMC_CMC_SORTEDLIST_CORE_HEADER(BODY) \ + CMC_CMC_SORTEDLIST_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_SORTEDLIST_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) +#define CMC_CMC_SORTEDLIST_CORE_HEADER(BODY) \ + CMC_CMC_SORTEDLIST_CORE_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_SORTEDLIST_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_SORTEDLIST_SOURCE(PFX, SNAME, V) +#define CMC_CMC_SORTEDLIST_CORE_SOURCE(BODY) \ + CMC_CMC_SORTEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \ - \ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flag if the list is sorted or not, used by lazy evaluation */ \ - bool is_sorted; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* List Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target list */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_list_); \ - void PFX##_free(struct SNAME *_list_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_list_, V value); \ - bool PFX##_remove(struct SNAME *_list_, size_t index); \ - /* Element Access */ \ - V PFX##_max(struct SNAME *_list_); \ - V PFX##_min(struct SNAME *_list_); \ - V PFX##_get(struct SNAME *_list_, size_t index); \ - size_t PFX##_index_of(struct SNAME *_list_, V value, bool from_start); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_list_, V value); \ - bool PFX##_empty(struct SNAME *_list_); \ - bool PFX##_full(struct SNAME *_list_); \ - size_t PFX##_count(struct SNAME *_list_); \ - size_t PFX##_capacity(struct SNAME *_list_); \ - int PFX##_flag(struct SNAME *_list_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_list_, size_t capacity); \ - void PFX##_sort(struct SNAME *_list_); \ - struct SNAME *PFX##_copy_of(struct SNAME *_list_); \ - bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_list_); \ - bool PFX##_print(struct SNAME *_list_, FILE *fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_SORTEDLIST_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* List Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Flag if the list is sorted or not, used by lazy evaluation */ \ + bool is_sorted; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* List Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target list */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index); \ + /* Element Access */ \ + V CMC_(PFX, _max)(struct SNAME * _list_); \ + V CMC_(PFX, _min)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ + bool from_start); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + bool CMC_(PFX, _full)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ + void CMC_(PFX, _sort)(struct SNAME * _list_); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_SORTEDLIST_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_SORTEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ - static size_t PFX##_impl_binary_search_first(struct SNAME *_list_, \ - V value); \ - static size_t PFX##_impl_binary_search_last(struct SNAME *_list_, \ - V value); \ - void PFX##_impl_sort_quicksort(V *array, int (*cmp)(V, V), size_t low, \ - size_t high); \ - void PFX##_impl_sort_insertion(V *array, int (*cmp)(V, V), size_t low, \ - size_t high); \ + static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, \ + V value); \ + static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, \ + V value); \ + void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), \ + size_t low, size_t high); \ + void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), \ + size_t low, size_t high); \ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -217,7 +229,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " _list_->capacity = capacity; \ _list_->count = 0; \ _list_->is_sorted = false; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ _list_->f_val = f_val; \ _list_->alloc = alloc; \ _list_->callbacks = NULL; \ @@ -225,9 +237,9 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return _list_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ if (capacity < 1) \ return NULL; \ @@ -251,7 +263,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " _list_->capacity = capacity; \ _list_->count = 0; \ _list_->is_sorted = false; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ _list_->f_val = f_val; \ _list_->alloc = alloc; \ _list_->callbacks = callbacks; \ @@ -259,7 +271,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return _list_; \ } \ \ - void PFX##_clear(struct SNAME *_list_) \ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ { \ if (_list_->f_val->free) \ { \ @@ -270,10 +282,10 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ \ _list_->count = 0; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_list_) \ + void CMC_(PFX, _free)(struct SNAME * _list_) \ { \ if (_list_->f_val->free) \ { \ @@ -285,8 +297,9 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " _list_->alloc->free(_list_); \ } \ \ - void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ @@ -295,21 +308,21 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " \ _list_->callbacks = callbacks; \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_insert(struct SNAME *_list_, V value) \ + bool CMC_(PFX, _insert)(struct SNAME * _list_, V value) \ { \ - if (PFX##_full(_list_)) \ + if (CMC_(PFX, _full)(_list_)) \ { \ - if (!PFX##_resize(_list_, _list_->capacity * 2)) \ + if (!CMC_(PFX, _resize)(_list_, _list_->capacity * 2)) \ return false; \ } \ \ _list_->buffer[_list_->count++] = value; \ \ _list_->is_sorted = false; \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->create) \ _list_->callbacks->create(); \ @@ -317,17 +330,17 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return true; \ } \ \ - bool PFX##_remove(struct SNAME *_list_, size_t index) \ + bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return false; \ } \ \ @@ -336,7 +349,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " \ _list_->buffer[--_list_->count] = (V){ 0 }; \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->delete) \ _list_->callbacks->delete (); \ @@ -344,17 +357,17 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return true; \ } \ \ - V PFX##_max(struct SNAME *_list_) \ + V CMC_(PFX, _max)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - PFX##_sort(_list_); \ + CMC_(PFX, _sort)(_list_); \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -362,17 +375,17 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return _list_->buffer[_list_->count - 1]; \ } \ \ - V PFX##_min(struct SNAME *_list_) \ + V CMC_(PFX, _min)(struct SNAME * _list_) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - PFX##_sort(_list_); \ + CMC_(PFX, _sort)(_list_); \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -380,23 +393,23 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return _list_->buffer[0]; \ } \ \ - V PFX##_get(struct SNAME *_list_, size_t index) \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ { \ - _list_->flag = cmc_flags.EMPTY; \ + _list_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ if (index >= _list_->count) \ { \ - _list_->flag = cmc_flags.RANGE; \ + _list_->flag = CMC_FLAG_RANGE; \ return (V){ 0 }; \ } \ \ - PFX##_sort(_list_); \ + CMC_(PFX, _sort)(_list_); \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ @@ -404,71 +417,73 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return _list_->buffer[index]; \ } \ \ - size_t PFX##_index_of(struct SNAME *_list_, V value, bool from_start) \ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ + bool from_start) \ { \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ - PFX##_sort(_list_); \ + CMC_(PFX, _sort)(_list_); \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ \ if (from_start) \ { \ - return PFX##_impl_binary_search_first(_list_, value); \ + return CMC_(PFX, _impl_binary_search_first)(_list_, value); \ } \ \ - return PFX##_impl_binary_search_last(_list_, value); \ + return CMC_(PFX, _impl_binary_search_last)(_list_, value); \ } \ \ - bool PFX##_contains(struct SNAME *_list_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ { \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ return false; \ \ - PFX##_sort(_list_); \ + CMC_(PFX, _sort)(_list_); \ \ if (_list_->callbacks && _list_->callbacks->read) \ _list_->callbacks->read(); \ \ - return PFX##_impl_binary_search_first(_list_, value) < _list_->count; \ + return CMC_(PFX, _impl_binary_search_first)(_list_, value) < \ + _list_->count; \ } \ \ - bool PFX##_empty(struct SNAME *_list_) \ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ { \ return _list_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_list_) \ + bool CMC_(PFX, _full)(struct SNAME * _list_) \ { \ return _list_->count >= _list_->capacity; \ } \ \ - size_t PFX##_count(struct SNAME *_list_) \ + size_t CMC_(PFX, _count)(struct SNAME * _list_) \ { \ return _list_->count; \ } \ \ - size_t PFX##_capacity(struct SNAME *_list_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ { \ return _list_->capacity; \ } \ \ - int PFX##_flag(struct SNAME *_list_) \ + int CMC_(PFX, _flag)(struct SNAME * _list_) \ { \ return _list_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_list_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \ { \ if (_list_->capacity == capacity) \ goto success; \ \ if (capacity < _list_->count) \ { \ - _list_->flag = cmc_flags.INVALID; \ + _list_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ @@ -477,7 +492,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " \ if (!new_buffer) \ { \ - _list_->flag = cmc_flags.ALLOC; \ + _list_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -488,7 +503,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " \ success: \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (_list_->callbacks && _list_->callbacks->resize) \ _list_->callbacks->resize(); \ @@ -496,28 +511,28 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return true; \ } \ \ - void PFX##_sort(struct SNAME *_list_) \ + void CMC_(PFX, _sort)(struct SNAME * _list_) \ { \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ if (!_list_->is_sorted && _list_->count > 1) \ { \ - PFX##_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, \ - _list_->count - 1); \ + CMC_(PFX, _impl_sort_quicksort) \ + (_list_->buffer, _list_->f_val->cmp, 0, _list_->count - 1); \ \ _list_->is_sorted = true; \ } \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_list_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ { \ struct SNAME *result = \ - PFX##_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, \ - _list_->callbacks); \ + CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, \ + _list_->alloc, _list_->callbacks); \ \ if (!result) \ { \ - _list_->flag = cmc_flags.ERROR; \ + _list_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ @@ -531,18 +546,18 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " \ result->count = _list_->count; \ \ - _list_->flag = cmc_flags.OK; \ + _list_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ { \ if (_list1_->count != _list2_->count) \ return false; \ \ - PFX##_sort(_list1_); \ - PFX##_sort(_list2_); \ + CMC_(PFX, _sort)(_list1_); \ + CMC_(PFX, _sort)(_list2_); \ \ for (size_t i = 0; i < _list1_->count; i++) \ { \ @@ -554,12 +569,12 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_list_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ { \ struct cmc_string str; \ struct SNAME *l_ = _list_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_sortedlist, \ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_sortedlist, \ #SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \ l_->is_sorted ? "true" : "false", l_->flag, \ l_->f_val, l_->alloc, l_->callbacks); \ @@ -567,9 +582,9 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_list_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ { \ - PFX##_sort(_list_); \ + CMC_(PFX, _sort)(_list_); \ \ for (size_t i = 0; i < _list_->count; i++) \ { \ @@ -580,54 +595,54 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - PFX##_sort(target); \ + CMC_(PFX, _sort)(target); \ \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - PFX##_sort(target); \ + CMC_(PFX, _sort)(target); \ \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ iter.cursor = target->count - 1; \ \ return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ return true; \ } \ @@ -635,11 +650,11 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->cursor = iter->target->count - 1; \ iter->end = true; \ \ @@ -649,7 +664,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -660,14 +675,14 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor++; \ \ return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -678,7 +693,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor--; \ \ @@ -686,7 +701,8 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -700,7 +716,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " if (steps == 0 || iter->cursor + steps >= iter->target->count) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor += steps; \ \ @@ -708,7 +724,8 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -722,7 +739,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " if (steps == 0 || iter->cursor < steps) \ return false; \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor -= steps; \ \ @@ -731,36 +748,37 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->cursor > index) \ - return PFX##_iter_rewind(iter, iter->cursor - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ else if (iter->cursor < index) \ - return PFX##_iter_advance(iter, index - iter->cursor); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor]; \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->cursor; \ } \ \ - static size_t PFX##_impl_binary_search_first(struct SNAME *_list_, \ - V value) \ + static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, \ + V value) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ return 1; \ \ size_t L = 0; \ @@ -783,9 +801,10 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " return _list_->count; \ } \ \ - static size_t PFX##_impl_binary_search_last(struct SNAME *_list_, V value) \ + static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, \ + V value) \ { \ - if (PFX##_empty(_list_)) \ + if (CMC_(PFX, _empty)(_list_)) \ return 1; \ \ size_t L = 0; \ @@ -812,8 +831,8 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " /* - Hybrid: uses insertion sort for small arrays */ \ /* - Partition: Lomuto's Method */ \ /* - Tail recursion: minimize recursion depth */ \ - void PFX##_impl_sort_quicksort(V *array, int (*cmp)(V, V), size_t low, \ - size_t high) \ + void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), \ + size_t low, size_t high) \ { \ while (low < high) \ { \ @@ -821,7 +840,7 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " /* insertion sort do the job */ \ if (high - low < 10) \ { \ - PFX##_impl_sort_insertion(array, cmp, low, high); \ + CMC_(PFX, _impl_sort_insertion)(array, cmp, low, high); \ break; \ } \ else \ @@ -850,13 +869,15 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " /* Tail recursion */ \ if (pindex - low < high - pindex) \ { \ - PFX##_impl_sort_quicksort(array, cmp, low, pindex - 1); \ + CMC_(PFX, _impl_sort_quicksort) \ + (array, cmp, low, pindex - 1); \ \ low = pindex + 1; \ } \ else \ { \ - PFX##_impl_sort_quicksort(array, cmp, pindex + 1, high); \ + CMC_(PFX, _impl_sort_quicksort) \ + (array, cmp, pindex + 1, high); \ \ high = pindex - 1; \ } \ @@ -864,8 +885,8 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " } \ } \ \ - void PFX##_impl_sort_insertion(V *array, int (*cmp)(V, V), size_t low, \ - size_t high) \ + void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), \ + size_t low, size_t high) \ { \ for (size_t i = low + 1; i <= high; i++) \ { \ @@ -882,4 +903,4 @@ static const char *cmc_string_fmt_sortedlist = "struct %s<%s> " } \ } -#endif /* CMC_SORTEDLIST_H */ +#endif /* CMC_CMC_SORTEDLIST_H */ diff --git a/src/cmc/stack.h b/src/cmc/stack.h index 1efa5f0..e34dc3f 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -25,8 +25,8 @@ * expression evaluation, syntax parsing and many more. */ -#ifndef CMC_STACK_H -#define CMC_STACK_H +#ifndef CMC_CMC_STACK_H +#define CMC_CMC_STACK_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -37,153 +37,164 @@ * Stack specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_stack = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_STACK(PFX, SNAME, V) \ - CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V) +/** + * Core Stack implementation + */ +#define CMC_CMC_STACK_CORE(BODY) \ + CMC_CMC_STACK_CORE_HEADER(BODY) \ + CMC_CMC_STACK_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_STACK_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) +#define CMC_CMC_STACK_CORE_HEADER(BODY) \ + CMC_CMC_STACK_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_STACK_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V) +#define CMC_CMC_STACK_CORE_SOURCE(BODY) \ + CMC_CMC_STACK_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \ - \ - /* Stack Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Stack Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target stack */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_stack_); \ - void PFX##_free(struct SNAME *_stack_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_stack_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_push(struct SNAME *_stack_, V value); \ - bool PFX##_pop(struct SNAME *_stack_); \ - /* Element Access */ \ - V PFX##_top(struct SNAME *_stack_); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_stack_, V value); \ - bool PFX##_empty(struct SNAME *_stack_); \ - bool PFX##_full(struct SNAME *_stack_); \ - size_t PFX##_count(struct SNAME *_stack_); \ - size_t PFX##_capacity(struct SNAME *_stack_); \ - int PFX##_flag(struct SNAME *_stack_); \ - /* Collection Utility */ \ - bool PFX##_resize(struct SNAME *_stack_, size_t capacity); \ - struct SNAME *PFX##_copy_of(struct SNAME *_stack_); \ - bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_stack_); \ - bool PFX##_print(struct SNAME *_stack_, FILE *fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); +#define CMC_CMC_STACK_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Stack Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Stack Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target stack */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _stack_); \ + void CMC_(PFX, _free)(struct SNAME * _stack_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _stack_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push)(struct SNAME * _stack_, V value); \ + bool CMC_(PFX, _pop)(struct SNAME * _stack_); \ + /* Element Access */ \ + V CMC_(PFX, _top)(struct SNAME * _stack_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _stack_); \ + bool CMC_(PFX, _full)(struct SNAME * _stack_); \ + size_t CMC_(PFX, _count)(struct SNAME * _stack_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _stack_); \ + int CMC_(PFX, _flag)(struct SNAME * _stack_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_); \ + bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _stack_); \ + bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_STACK_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ /* None */ \ \ - struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ \ @@ -208,7 +219,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " \ _stack_->capacity = capacity; \ _stack_->count = 0; \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ _stack_->f_val = f_val; \ _stack_->alloc = alloc; \ _stack_->callbacks = NULL; \ @@ -216,9 +227,9 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return _stack_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ if (capacity < 1) \ return NULL; \ @@ -243,7 +254,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " \ _stack_->capacity = capacity; \ _stack_->count = 0; \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ _stack_->f_val = f_val; \ _stack_->alloc = alloc; \ _stack_->callbacks = callbacks; \ @@ -251,7 +262,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return _stack_; \ } \ \ - void PFX##_clear(struct SNAME *_stack_) \ + void CMC_(PFX, _clear)(struct SNAME * _stack_) \ { \ if (_stack_->f_val->free) \ { \ @@ -262,10 +273,10 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \ \ _stack_->count = 0; \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_stack_) \ + void CMC_(PFX, _free)(struct SNAME * _stack_) \ { \ if (_stack_->f_val->free) \ { \ @@ -277,8 +288,9 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " _stack_->alloc->free(_stack_); \ } \ \ - void PFX##_customize(struct SNAME *_stack_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _stack_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _stack_->alloc = &cmc_alloc_node_default; \ @@ -287,20 +299,20 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " \ _stack_->callbacks = callbacks; \ \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_push(struct SNAME *_stack_, V value) \ + bool CMC_(PFX, _push)(struct SNAME * _stack_, V value) \ { \ - if (PFX##_full(_stack_)) \ + if (CMC_(PFX, _full)(_stack_)) \ { \ - if (!PFX##_resize(_stack_, _stack_->capacity * 2)) \ + if (!CMC_(PFX, _resize)(_stack_, _stack_->capacity * 2)) \ return false; \ } \ \ _stack_->buffer[_stack_->count++] = value; \ \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ \ if (_stack_->callbacks && _stack_->callbacks->create) \ _stack_->callbacks->create(); \ @@ -308,17 +320,17 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return true; \ } \ \ - bool PFX##_pop(struct SNAME *_stack_) \ + bool CMC_(PFX, _pop)(struct SNAME * _stack_) \ { \ - if (PFX##_empty(_stack_)) \ + if (CMC_(PFX, _empty)(_stack_)) \ { \ - _stack_->flag = cmc_flags.EMPTY; \ + _stack_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ _stack_->buffer[--_stack_->count] = (V){ 0 }; \ \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ \ if (_stack_->callbacks && _stack_->callbacks->delete) \ _stack_->callbacks->delete (); \ @@ -326,15 +338,15 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return true; \ } \ \ - V PFX##_top(struct SNAME *_stack_) \ + V CMC_(PFX, _top)(struct SNAME * _stack_) \ { \ - if (PFX##_empty(_stack_)) \ + if (CMC_(PFX, _empty)(_stack_)) \ { \ - _stack_->flag = cmc_flags.EMPTY; \ + _stack_->flag = CMC_FLAG_EMPTY; \ return (V){ 0 }; \ } \ \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ \ if (_stack_->callbacks && _stack_->callbacks->read) \ _stack_->callbacks->read(); \ @@ -342,9 +354,9 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return _stack_->buffer[_stack_->count - 1]; \ } \ \ - bool PFX##_contains(struct SNAME *_stack_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value) \ { \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ \ bool result = false; \ \ @@ -363,39 +375,39 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_stack_) \ + bool CMC_(PFX, _empty)(struct SNAME * _stack_) \ { \ return _stack_->count == 0; \ } \ \ - bool PFX##_full(struct SNAME *_stack_) \ + bool CMC_(PFX, _full)(struct SNAME * _stack_) \ { \ return _stack_->count >= _stack_->capacity; \ } \ \ - size_t PFX##_count(struct SNAME *_stack_) \ + size_t CMC_(PFX, _count)(struct SNAME * _stack_) \ { \ return _stack_->count; \ } \ \ - size_t PFX##_capacity(struct SNAME *_stack_) \ + size_t CMC_(PFX, _capacity)(struct SNAME * _stack_) \ { \ return _stack_->capacity; \ } \ \ - int PFX##_flag(struct SNAME *_stack_) \ + int CMC_(PFX, _flag)(struct SNAME * _stack_) \ { \ return _stack_->flag; \ } \ \ - bool PFX##_resize(struct SNAME *_stack_, size_t capacity) \ + bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity) \ { \ if (_stack_->capacity == capacity) \ goto success; \ \ if (capacity < _stack_->count) \ { \ - _stack_->flag = cmc_flags.INVALID; \ + _stack_->flag = CMC_FLAG_INVALID; \ return false; \ } \ \ @@ -404,7 +416,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " \ if (!new_buffer) \ { \ - _stack_->flag = cmc_flags.ALLOC; \ + _stack_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -415,7 +427,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " \ success: \ \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ \ if (_stack_->callbacks && _stack_->callbacks->resize) \ _stack_->callbacks->resize(); \ @@ -423,15 +435,15 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_stack_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_) \ { \ struct SNAME *result = \ - PFX##_new_custom(_stack_->capacity, _stack_->f_val, \ - _stack_->alloc, _stack_->callbacks); \ + CMC_(PFX, _new_custom)(_stack_->capacity, _stack_->f_val, \ + _stack_->alloc, _stack_->callbacks); \ \ if (!result) \ { \ - _stack_->flag = cmc_flags.ERROR; \ + _stack_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ @@ -446,15 +458,15 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " \ result->count = _stack_->count; \ \ - _stack_->flag = cmc_flags.OK; \ + _stack_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_) \ { \ - _stack1_->flag = cmc_flags.OK; \ - _stack2_->flag = cmc_flags.OK; \ + _stack1_->flag = CMC_FLAG_OK; \ + _stack2_->flag = CMC_FLAG_OK; \ \ if (_stack1_->count != _stack2_->count) \ return false; \ @@ -469,19 +481,19 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_stack_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _stack_) \ { \ struct cmc_string str; \ struct SNAME *s_ = _stack_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, #SNAME, \ - #V, s_, s_->buffer, s_->capacity, s_->count, \ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_stack, \ + #SNAME, #V, s_, s_->buffer, s_->capacity, s_->count, \ s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_stack_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr) \ { \ for (size_t i = 0; i < _stack_->count; i++) \ { \ @@ -492,50 +504,50 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ iter.cursor = target->count - 1; \ \ return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = iter->target->count - 1; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ return true; \ } \ @@ -543,12 +555,12 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->cursor = 0; \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->end = true; \ \ return true; \ @@ -557,7 +569,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -568,14 +580,14 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor--; \ \ return true; \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -586,7 +598,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor++; \ \ @@ -594,7 +606,8 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -608,7 +621,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " if (steps == 0 || iter->cursor < steps) \ return false; \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor -= steps; \ \ @@ -616,7 +629,8 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -630,7 +644,7 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " if (steps == 0 || iter->cursor + steps >= iter->target->count) \ return false; \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ iter->cursor += steps; \ \ @@ -639,41 +653,42 @@ static const char *cmc_string_fmt_stack = "struct %s<%s> " \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->cursor > index) \ - return PFX##_iter_advance(iter, iter->cursor - index); \ + return CMC_(PFX, _iter_advance)(iter, iter->cursor - index); \ else if (iter->cursor < index) \ - return PFX##_iter_rewind(iter, index - iter->cursor); \ + return CMC_(PFX, _iter_rewind)(iter, index - iter->cursor); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->target->buffer[iter->cursor]; \ } \ \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return NULL; \ \ return &(iter->target->buffer[iter->cursor]); \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return 0; \ \ return iter->target->count - 1 - iter->cursor; \ } -#endif /* CMC_STACK_H */ +#endif /* CMC_CMC_STACK_H */ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index ebc1474..d5c3528 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -16,8 +16,8 @@ * tree called AVL Tree that uses the height of nodes to keep its keys balanced. */ -#ifndef CMC_TREEMAP_H -#define CMC_TREEMAP_H +#ifndef CMC_CMC_TREEMAP_H +#define CMC_CMC_TREEMAP_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -28,36 +28,41 @@ * TreeMap specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " - "at %p { " - "root:%p, " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "f_key:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " + "at %p { " + "root:%p, " + "count:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "f_key:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_TREEMAP(PFX, SNAME, K, V) \ - CMC_GENERATE_TREEMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V) +/** + * Core TreeMap implementation + */ +#define CMC_CMC_TREEMAP_CORE(BODY) \ + CMC_CMC_TREEMAP_CORE_HEADER(BODY) \ + CMC_CMC_TREEMAP_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_TREEMAP_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_TREEMAP_HEADER(PFX, SNAME, K, V) +#define CMC_CMC_TREEMAP_CORE_HEADER(BODY) \ + CMC_CMC_TREEMAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_TREEMAP_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V) +#define CMC_CMC_TREEMAP_CORE_SOURCE(BODY) \ + CMC_CMC_TREEMAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_TREEMAP_HEADER(PFX, SNAME, K, V) \ +#define CMC_CMC_TREEMAP_CORE_HEADER_(PFX, SNAME, K, V) \ \ /* Treemap Structure */ \ struct SNAME \ { \ /* Root node */ \ - struct SNAME##_node *root; \ + struct CMC_DEF_NODE(SNAME) * root; \ \ /* Current amount of keys */ \ size_t count; \ @@ -66,10 +71,10 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " int flag; \ \ /* Key function table */ \ - struct SNAME##_fkey *f_key; \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ \ /* Value function table */ \ - struct SNAME##_fval *f_val; \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ \ /* Custom allocation functions */ \ struct cmc_alloc_node *alloc; \ @@ -79,7 +84,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " }; \ \ /* Treemap Node */ \ - struct SNAME##_node \ + struct CMC_DEF_NODE(SNAME) \ { \ /* Node Key */ \ K key; \ @@ -91,17 +96,17 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " unsigned char height; \ \ /* Right child node or subtree */ \ - struct SNAME##_node *right; \ + struct CMC_DEF_NODE(SNAME) * right; \ \ /* Left child node or subtree */ \ - struct SNAME##_node *left; \ + struct CMC_DEF_NODE(SNAME) * left; \ \ /* Parent node */ \ - struct SNAME##_node *parent; \ + struct CMC_DEF_NODE(SNAME) * parent; \ }; \ \ /* Key struct function table */ \ - struct SNAME##_fkey \ + struct CMC_DEF_FKEY(SNAME) \ { \ /* Comparator function */ \ int (*cmp)(K, K); \ @@ -123,7 +128,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " }; \ \ /* Value struct function table */ \ - struct SNAME##_fval \ + struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ int (*cmp)(V, V); \ @@ -145,19 +150,19 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " }; \ \ /* Treemap Iterator */ \ - struct SNAME##_iter \ + struct CMC_DEF_ITER(SNAME) \ { \ /* Target treemap */ \ struct SNAME *target; \ \ /* Cursor's current node */ \ - struct SNAME##_node *cursor; \ + struct CMC_DEF_NODE(SNAME) * cursor; \ \ /* The first node in the iteration */ \ - struct SNAME##_node *first; \ + struct CMC_DEF_NODE(SNAME) * first; \ \ /* The last node in the iteration */ \ - struct SNAME##_node *last; \ + struct CMC_DEF_NODE(SNAME) * last; \ \ /* Keeps track of relative index to the iteration of elements */ \ size_t index; \ @@ -171,76 +176,85 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom( \ - struct SNAME##_fkey *f_key, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_map_); \ - void PFX##_free(struct SNAME *_map_); \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_map_, K key, V value); \ - bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value); \ - bool PFX##_remove(struct SNAME *_map_, K key, V *out_value); \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ + V * old_value); \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ /* Element Access */ \ - bool PFX##_max(struct SNAME *_map_, K *key, V *value); \ - bool PFX##_min(struct SNAME *_map_, K *key, V *value); \ - V PFX##_get(struct SNAME *_map_, K key); \ - V *PFX##_get_ref(struct SNAME *_map_, K key); \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ /* Collection State */ \ - bool PFX##_contains(struct SNAME *_map_, K key); \ - bool PFX##_empty(struct SNAME *_map_); \ - size_t PFX##_count(struct SNAME *_map_); \ - int PFX##_flag(struct SNAME *_map_); \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ /* Collection Utility */ \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_); \ - bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_map_); \ - bool PFX##_print(struct SNAME *_map_, FILE *fptr); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ \ /* Iterator Functions */ \ /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ /* Iterator Access */ \ - K PFX##_iter_key(struct SNAME##_iter *iter); \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V) \ +#define CMC_CMC_TREEMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ \ /* Implementation Detail Functions */ \ - static struct SNAME##_node *PFX##_impl_new_node(struct SNAME *_map_, \ - K key, V value); \ - static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_map_, \ - K key); \ - static unsigned char PFX##_impl_h(struct SNAME##_node *node); \ - static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node); \ - static void PFX##_impl_rotate_right(struct SNAME##_node **Z); \ - static void PFX##_impl_rotate_left(struct SNAME##_node **Z); \ - static void PFX##_impl_rebalance(struct SNAME *_map_, \ - struct SNAME##_node *node); \ + static struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value); \ + static struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key); \ + static unsigned char CMC_(PFX, \ + _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \ + static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * \ + node); \ + static void CMC_(PFX, \ + _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \ + static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z); \ + static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, \ + struct CMC_DEF_NODE(SNAME) * node); \ \ - struct SNAME *PFX##_new(struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ if (!f_key || !f_val) \ return NULL; \ @@ -254,7 +268,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->count = 0; \ _map_->root = NULL; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ _map_->f_key = f_key; \ _map_->f_val = f_val; \ _map_->alloc = alloc; \ @@ -263,9 +277,10 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return _map_; \ } \ \ - struct SNAME *PFX##_new_custom( \ - struct SNAME##_fkey *f_key, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!f_key || !f_val) \ return NULL; \ @@ -280,7 +295,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->count = 0; \ _map_->root = NULL; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ _map_->f_key = f_key; \ _map_->f_val = f_val; \ _map_->alloc = alloc; \ @@ -289,16 +304,16 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return _map_; \ } \ \ - void PFX##_clear(struct SNAME *_map_) \ + void CMC_(PFX, _clear)(struct SNAME * _map_) \ { \ - struct SNAME##_node *scan = _map_->root; \ - struct SNAME##_node *up = NULL; \ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ + struct CMC_DEF_NODE(SNAME) *up = NULL; \ \ while (scan != NULL) \ { \ if (scan->left != NULL) \ { \ - struct SNAME##_node *left = scan->left; \ + struct CMC_DEF_NODE(SNAME) *left = scan->left; \ \ scan->left = up; \ up = scan; \ @@ -306,7 +321,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " } \ else if (scan->right != NULL) \ { \ - struct SNAME##_node *right = scan->right; \ + struct CMC_DEF_NODE(SNAME) *right = scan->right; \ \ scan->left = up; \ scan->right = NULL; \ @@ -352,18 +367,19 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->count = 0; \ _map_->root = NULL; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_map_) \ + void CMC_(PFX, _free)(struct SNAME * _map_) \ { \ - PFX##_clear(_map_); \ + CMC_(PFX, _clear)(_map_); \ \ _map_->alloc->free(_map_); \ } \ \ - void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ @@ -372,25 +388,25 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->callbacks = callbacks; \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_insert(struct SNAME *_map_, K key, V value) \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->root = PFX##_impl_new_node(_map_, key, value); \ + _map_->root = CMC_(PFX, _impl_new_node)(_map_, key, value); \ \ if (!_map_->root) \ { \ - _map_->flag = cmc_flags.ALLOC; \ + _map_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ } \ else \ { \ - struct SNAME##_node *scan = _map_->root; \ - struct SNAME##_node *parent = scan; \ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ + struct CMC_DEF_NODE(SNAME) *parent = scan; \ \ while (scan != NULL) \ { \ @@ -402,20 +418,20 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " scan = scan->right; \ else \ { \ - _map_->flag = cmc_flags.DUPLICATE; \ + _map_->flag = CMC_FLAG_DUPLICATE; \ return false; \ } \ } \ \ - struct SNAME##_node *node; \ + struct CMC_DEF_NODE(SNAME) * node; \ \ if (_map_->f_key->cmp(parent->key, key) > 0) \ { \ - parent->left = PFX##_impl_new_node(_map_, key, value); \ + parent->left = CMC_(PFX, _impl_new_node)(_map_, key, value); \ \ if (!parent->left) \ { \ - _map_->flag = cmc_flags.ALLOC; \ + _map_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -424,11 +440,11 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " } \ else \ { \ - parent->right = PFX##_impl_new_node(_map_, key, value); \ + parent->right = CMC_(PFX, _impl_new_node)(_map_, key, value); \ \ if (!parent->right) \ { \ - _map_->flag = cmc_flags.ALLOC; \ + _map_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -436,11 +452,11 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " node = parent->right; \ } \ \ - PFX##_impl_rebalance(_map_, node); \ + CMC_(PFX, _impl_rebalance)(_map_, node); \ } \ \ _map_->count++; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->create) \ _map_->callbacks->create(); \ @@ -448,13 +464,15 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value) \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ + V * old_value) \ { \ - struct SNAME##_node *node = PFX##_impl_get_node(_map_, key); \ + struct CMC_DEF_NODE(SNAME) *node = \ + CMC_(PFX, _impl_get_node)(_map_, key); \ \ if (!node) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ @@ -463,7 +481,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ node->value = new_value; \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->update) \ _map_->callbacks->update(); \ @@ -471,26 +489,27 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_remove(struct SNAME *_map_, K key, V *out_value) \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *node = PFX##_impl_get_node(_map_, key); \ + struct CMC_DEF_NODE(SNAME) *node = \ + CMC_(PFX, _impl_get_node)(_map_, key); \ \ if (!node) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ if (out_value) \ *out_value = node->value; \ \ - struct SNAME##_node *temp = NULL, *unbalanced = NULL; \ + struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \ \ bool is_root = node->parent == NULL; \ \ @@ -596,13 +615,13 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " } \ \ if (unbalanced != NULL) \ - PFX##_impl_rebalance(_map_, unbalanced); \ + CMC_(PFX, _impl_rebalance)(_map_, unbalanced); \ \ if (_map_->count == 0) \ _map_->root = NULL; \ \ _map_->count--; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->delete) \ _map_->callbacks->delete (); \ @@ -610,15 +629,15 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_max(struct SNAME *_map_, K *key, V *value) \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *scan = _map_->root; \ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ \ while (scan->right != NULL) \ scan = scan->right; \ @@ -628,7 +647,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " if (value) \ *value = scan->value; \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -636,15 +655,15 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return true; \ } \ \ - bool PFX##_min(struct SNAME *_map_, K *key, V *value) \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *scan = _map_->root; \ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ \ while (scan->left != NULL) \ scan = scan->left; \ @@ -654,7 +673,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " if (value) \ *value = scan->value; \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -662,23 +681,24 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return true; \ } \ \ - V PFX##_get(struct SNAME *_map_, K key) \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *node = PFX##_impl_get_node(_map_, key); \ + struct CMC_DEF_NODE(SNAME) *node = \ + CMC_(PFX, _impl_get_node)(_map_, key); \ \ if (!node) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return (V){ 0 }; \ } \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -686,23 +706,24 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return node->value; \ } \ \ - V *PFX##_get_ref(struct SNAME *_map_, K key) \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ { \ - if (PFX##_empty(_map_)) \ + if (CMC_(PFX, _empty)(_map_)) \ { \ - _map_->flag = cmc_flags.EMPTY; \ + _map_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *node = PFX##_impl_get_node(_map_, key); \ + struct CMC_DEF_NODE(SNAME) *node = \ + CMC_(PFX, _impl_get_node)(_map_, key); \ \ if (!node) \ { \ - _map_->flag = cmc_flags.NOT_FOUND; \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ return NULL; \ } \ \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -710,9 +731,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return &(node->value); \ } \ \ - bool PFX##_contains(struct SNAME *_map_, K key) \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ { \ - bool result = PFX##_impl_get_node(_map_, key) != NULL; \ + bool result = CMC_(PFX, _impl_get_node)(_map_, key) != NULL; \ \ if (_map_->callbacks && _map_->callbacks->read) \ _map_->callbacks->read(); \ @@ -720,40 +741,40 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_map_) \ + bool CMC_(PFX, _empty)(struct SNAME * _map_) \ { \ return _map_->count == 0; \ } \ \ - size_t PFX##_count(struct SNAME *_map_) \ + size_t CMC_(PFX, _count)(struct SNAME * _map_) \ { \ return _map_->count; \ } \ \ - int PFX##_flag(struct SNAME *_map_) \ + int CMC_(PFX, _flag)(struct SNAME * _map_) \ { \ return _map_->flag; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_map_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ { \ /* Callback will be added later */ \ - struct SNAME *result = \ - PFX##_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, NULL); \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ \ if (!result) \ { \ - _map_->flag = cmc_flags.ERROR; \ + _map_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ /* TODO turn this into a normal loop */ \ - struct SNAME##_iter iter = PFX##_iter_start(_map_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - K key = PFX##_iter_key(&iter); \ - V value = PFX##_iter_value(&iter); \ + K key = CMC_(PFX, _iter_key)(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ if (_map_->f_key->cpy) \ key = _map_->f_key->cpy(key); \ @@ -761,56 +782,57 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " value = _map_->f_val->cpy(value); \ \ /* TODO check this for errors */ \ - PFX##_insert(result, key, value); \ + CMC_(PFX, _insert)(result, key, value); \ } \ \ result->callbacks = _map_->callbacks; \ - _map_->flag = cmc_flags.OK; \ + _map_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ { \ - _map1_->flag = cmc_flags.OK; \ - _map2_->flag = cmc_flags.OK; \ + _map1_->flag = CMC_FLAG_OK; \ + _map2_->flag = CMC_FLAG_OK; \ \ if (_map1_->count != _map2_->count) \ return false; \ \ /* TODO turn this into a normal loop */ \ - struct SNAME##_iter iter = PFX##_iter_start(_map1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - struct SNAME##_node *node = \ - PFX##_impl_get_node(_map2_, PFX##_iter_key(&iter)); \ + struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)( \ + _map2_, CMC_(PFX, _iter_key)(&iter)); \ \ if (node == NULL) \ return false; \ \ - if (_map1_->f_val->cmp(node->value, PFX##_iter_value(&iter)) != 0) \ + if (_map1_->f_val->cmp(node->value, \ + CMC_(PFX, _iter_value)(&iter)) != 0) \ return false; \ } \ \ return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_map_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ { \ struct cmc_string str; \ struct SNAME *m_ = _map_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_treemap, \ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treemap, \ #SNAME, #K, #V, m_, m_->root, m_->count, m_->flag, \ m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_map_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ { \ - struct SNAME##_node *root = _map_->root; \ + struct CMC_DEF_NODE(SNAME) *root = _map_->root; \ \ bool left_done = false; \ \ @@ -850,9 +872,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = target->root; \ @@ -860,9 +882,9 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " iter.last = NULL; \ iter.index = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ while (iter.cursor->left != NULL) \ iter.cursor = iter.cursor->left; \ @@ -877,19 +899,19 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = target->root; \ iter.first = NULL; \ iter.last = NULL; \ iter.index = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ while (iter.cursor->right != NULL) \ iter.cursor = iter.cursor->right; \ @@ -906,23 +928,23 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->index = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ iter->cursor = iter->first; \ \ return true; \ @@ -931,12 +953,12 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->end = true; \ iter->cursor = iter->last; \ \ @@ -946,7 +968,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -957,7 +979,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ if (iter->cursor->right != NULL) \ { \ @@ -986,7 +1008,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " } \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -997,7 +1019,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ if (iter->cursor->left != NULL) \ { \ @@ -1027,7 +1049,8 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -1042,13 +1065,14 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_next(iter); \ + CMC_(PFX, _iter_next)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -1063,60 +1087,61 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_prev(iter); \ + CMC_(PFX, _iter_prev)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ \ return true; \ } \ \ - K PFX##_iter_key(struct SNAME##_iter *iter) \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (K){ 0 }; \ \ return iter->cursor->key; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->cursor->value; \ } \ \ - V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return NULL; \ \ return &(iter->cursor->value); \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->index; \ } \ \ - static struct SNAME##_node *PFX##_impl_new_node(struct SNAME *_map_, \ - K key, V value) \ + static struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value) \ { \ - struct SNAME##_node *node = \ - _map_->alloc->malloc(sizeof(struct SNAME##_node)); \ + struct CMC_DEF_NODE(SNAME) *node = \ + _map_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ \ if (!node) \ return NULL; \ @@ -1131,10 +1156,10 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return node; \ } \ \ - static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_map_, \ - K key) \ + static struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key) \ { \ - struct SNAME##_node *scan = _map_->root; \ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ \ while (scan != NULL) \ { \ @@ -1149,7 +1174,7 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return NULL; \ } \ \ - static unsigned char PFX##_impl_h(struct SNAME##_node *node) \ + static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node) \ { \ if (node == NULL) \ return 0; \ @@ -1157,21 +1182,22 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " return node->height; \ } \ \ - static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node) \ + static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * \ + node) \ { \ if (node == NULL) \ return 0; \ \ - unsigned char h_l = PFX##_impl_h(node->left); \ - unsigned char h_r = PFX##_impl_h(node->right); \ + unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \ + unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \ \ return 1 + (h_l > h_r ? h_l : h_r); \ } \ \ - static void PFX##_impl_rotate_right(struct SNAME##_node **Z) \ + static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z) \ { \ - struct SNAME##_node *root = *Z; \ - struct SNAME##_node *new_root = root->left; \ + struct CMC_DEF_NODE(SNAME) *root = *Z; \ + struct CMC_DEF_NODE(SNAME) *new_root = root->left; \ \ if (root->parent != NULL) \ { \ @@ -1191,16 +1217,16 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ new_root->right = root; \ \ - root->height = PFX##_impl_hupdate(root); \ - new_root->height = PFX##_impl_hupdate(new_root); \ + root->height = CMC_(PFX, _impl_hupdate)(root); \ + new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ \ *Z = new_root; \ } \ \ - static void PFX##_impl_rotate_left(struct SNAME##_node **Z) \ + static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \ { \ - struct SNAME##_node *root = *Z; \ - struct SNAME##_node *new_root = root->right; \ + struct CMC_DEF_NODE(SNAME) *root = *Z; \ + struct CMC_DEF_NODE(SNAME) *new_root = root->right; \ \ if (root->parent != NULL) \ { \ @@ -1220,16 +1246,16 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " \ new_root->left = root; \ \ - root->height = PFX##_impl_hupdate(root); \ - new_root->height = PFX##_impl_hupdate(new_root); \ + root->height = CMC_(PFX, _impl_hupdate)(root); \ + new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ \ *Z = new_root; \ } \ \ - static void PFX##_impl_rebalance(struct SNAME *_map_, \ - struct SNAME##_node *node) \ + static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, \ + struct CMC_DEF_NODE(SNAME) * node) \ { \ - struct SNAME##_node *scan = node, *child = NULL; \ + struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \ \ int balance; \ bool is_root = false; \ @@ -1239,26 +1265,29 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " if (scan->parent == NULL) \ is_root = true; \ \ - scan->height = PFX##_impl_hupdate(scan); \ - balance = PFX##_impl_h(scan->right) - PFX##_impl_h(scan->left); \ + scan->height = CMC_(PFX, _impl_hupdate)(scan); \ + balance = CMC_(PFX, _impl_h)(scan->right) - \ + CMC_(PFX, _impl_h)(scan->left); \ \ if (balance >= 2) \ { \ child = scan->right; \ \ - if (PFX##_impl_h(child->right) < PFX##_impl_h(child->left)) \ - PFX##_impl_rotate_right(&(scan->right)); \ + if (CMC_(PFX, _impl_h)(child->right) < \ + CMC_(PFX, _impl_h)(child->left)) \ + CMC_(PFX, _impl_rotate_right)(&(scan->right)); \ \ - PFX##_impl_rotate_left(&scan); \ + CMC_(PFX, _impl_rotate_left)(&scan); \ } \ else if (balance <= -2) \ { \ child = scan->left; \ \ - if (PFX##_impl_h(child->left) < PFX##_impl_h(child->right)) \ - PFX##_impl_rotate_left(&(scan->left)); \ + if (CMC_(PFX, _impl_h)(child->left) < \ + CMC_(PFX, _impl_h)(child->right)) \ + CMC_(PFX, _impl_rotate_left)(&(scan->left)); \ \ - PFX##_impl_rotate_right(&scan); \ + CMC_(PFX, _impl_rotate_right)(&scan); \ } \ \ if (is_root) \ @@ -1271,4 +1300,4 @@ static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> " } \ } -#endif /* CMC_TREEMAP_H */ +#endif /* CMC_CMC_TREEMAP_H */ diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 2c2a103..eb853e3 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -16,8 +16,8 @@ * tree called AVL Tree that uses the height of nodes to keep its keys balanced. */ -#ifndef CMC_TREESET_H -#define CMC_TREESET_H +#ifndef CMC_CMC_TREESET_H +#define CMC_CMC_TREESET_H /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library @@ -28,207 +28,224 @@ * TreeSet specific * ------------------------------------------------------------------------- */ /* to_string format */ -static const char *cmc_string_fmt_treeset = "struct %s<%s> " - "at %p { " - "root:%p, " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; +static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " + "at %p { " + "root:%p, " + "count:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; -#define CMC_GENERATE_TREESET(PFX, SNAME, V) \ - CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) \ - CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V) +/** + * Core TreeSet implementation + */ +#define CMC_CMC_TREESET_CORE(BODY) \ + CMC_CMC_TREESET_CORE_HEADER(BODY) \ + CMC_CMC_TREESET_CORE_SOURCE(BODY) -#define CMC_WRAPGEN_TREESET_HEADER(PFX, SNAME, K, V) \ - CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) +#define CMC_CMC_TREESET_CORE_HEADER(BODY) \ + CMC_CMC_TREESET_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) -#define CMC_WRAPGEN_TREESET_SOURCE(PFX, SNAME, K, V) \ - CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V) +#define CMC_CMC_TREESET_CORE_SOURCE(BODY) \ + CMC_CMC_TREESET_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) \ - \ - /* Treeset Structure */ \ - struct SNAME \ - { \ - /* Root node */ \ - struct SNAME##_node *root; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct SNAME##_fval *f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Treeset Node */ \ - struct SNAME##_node \ - { \ - /* Node element */ \ - V value; \ - \ - /* Node height used by the AVL tree to keep it strictly balanced */ \ - unsigned char height; \ - \ - /* Right child node or subtree */ \ - struct SNAME##_node *right; \ - \ - /* Left child node or subtree */ \ - struct SNAME##_node *left; \ - \ - /* Parent node */ \ - struct SNAME##_node *parent; \ - }; \ - \ - /* Value struct function table */ \ - struct SNAME##_fval \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Treeset Iterator */ \ - struct SNAME##_iter \ - { \ - /* Target treeset */ \ - struct SNAME *target; \ - \ - /* Cursor's current node */ \ - struct SNAME##_node *cursor; \ - \ - /* The first node in the iteration */ \ - struct SNAME##_node *first; \ - \ - /* The last node in the iteration */ \ - struct SNAME##_node *last; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *PFX##_new(struct SNAME##_fval *f_val); \ - struct SNAME *PFX##_new_custom(struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - void PFX##_clear(struct SNAME *_set_); \ - void PFX##_free(struct SNAME *_set_); \ - /* Customization of Allocation and Callbacks */ \ - void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); \ - /* Collection Input and Output */ \ - bool PFX##_insert(struct SNAME *_set_, V value); \ - bool PFX##_remove(struct SNAME *_set_, V value); \ - /* Element Access */ \ - bool PFX##_max(struct SNAME *_set_, V *value); \ - bool PFX##_min(struct SNAME *_set_, V *value); \ - /* Collection State */ \ - bool PFX##_contains(struct SNAME *_set_, V value); \ - bool PFX##_empty(struct SNAME *_set_); \ - size_t PFX##_count(struct SNAME *_set_); \ - int PFX##_flag(struct SNAME *_set_); \ - /* Collection Utility */ \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_); \ - bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \ - struct cmc_string PFX##_to_string(struct SNAME *_set_); \ - bool PFX##_print(struct SNAME *_set_, FILE *fptr); \ - \ - /* Set Operations */ \ - struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \ - struct SNAME *PFX##_intersection(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - struct SNAME *PFX##_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_); \ - bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_); \ - bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \ - /* Iterator State */ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter); \ - /* Iterator Movement */ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter); \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter); \ - bool PFX##_iter_next(struct SNAME##_iter *iter); \ - bool PFX##_iter_prev(struct SNAME##_iter *iter); \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \ - /* Iterator Access */ \ - V PFX##_iter_value(struct SNAME##_iter *iter); \ - size_t PFX##_iter_index(struct SNAME##_iter *iter); \ - \ - /* Default Value */ \ - static inline V PFX##_impl_default_value(void) \ - { \ - V _empty_value_; \ - \ - memset(&_empty_value_, 0, sizeof(V)); \ - \ - return _empty_value_; \ +#define CMC_CMC_TREESET_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Treeset Structure */ \ + struct SNAME \ + { \ + /* Root node */ \ + struct CMC_DEF_NODE(SNAME) * root; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Treeset Node */ \ + struct CMC_DEF_NODE(SNAME) \ + { \ + /* Node element */ \ + V value; \ + \ + /* Node height used by the AVL tree to keep it strictly balanced */ \ + unsigned char height; \ + \ + /* Right child node or subtree */ \ + struct CMC_DEF_NODE(SNAME) * right; \ + \ + /* Left child node or subtree */ \ + struct CMC_DEF_NODE(SNAME) * left; \ + \ + /* Parent node */ \ + struct CMC_DEF_NODE(SNAME) * parent; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Treeset Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target treeset */ \ + struct SNAME *target; \ + \ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ + \ + /* The first node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * first; \ + \ + /* The last node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * last; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _set_); \ + void CMC_(PFX, _free)(struct SNAME * _set_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _set_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _set_); \ + size_t CMC_(PFX, _count)(struct SNAME * _set_); \ + int CMC_(PFX, _flag)(struct SNAME * _set_); \ + /* Collection Utility */ \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \ + \ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ + \ + /* Default Value */ \ + static inline V CMC_(PFX, _impl_default_value)(void) \ + { \ + V _empty_value_; \ + \ + memset(&_empty_value_, 0, sizeof(V)); \ + \ + return _empty_value_; \ } /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V) \ +#define CMC_CMC_TREESET_CORE_SOURCE_(PFX, SNAME, V) \ \ /* Implementation Detail Functions */ \ - static struct SNAME##_node *PFX##_impl_new_node(struct SNAME *_set_, \ - V value); \ - static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_set_, \ - V value); \ - static unsigned char PFX##_impl_h(struct SNAME##_node *node); \ - static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node); \ - static void PFX##_impl_rotate_right(struct SNAME##_node **Z); \ - static void PFX##_impl_rotate_left(struct SNAME##_node **Z); \ - static void PFX##_impl_rebalance(struct SNAME *_set_, \ - struct SNAME##_node *node); \ + static struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value); \ + static struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value); \ + static unsigned char CMC_(PFX, \ + _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \ + static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * \ + node); \ + static void CMC_(PFX, \ + _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \ + static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z); \ + static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, \ + struct CMC_DEF_NODE(SNAME) * node); \ \ - struct SNAME *PFX##_new(struct SNAME##_fval *f_val) \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ if (!f_val) \ return NULL; \ @@ -242,7 +259,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " \ _set_->count = 0; \ _set_->root = NULL; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ _set_->f_val = f_val; \ _set_->alloc = alloc; \ _set_->callbacks = NULL; \ @@ -250,9 +267,9 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return _set_; \ } \ \ - struct SNAME *PFX##_new_custom(struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!f_val) \ return NULL; \ @@ -267,7 +284,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " \ _set_->count = 0; \ _set_->root = NULL; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ _set_->f_val = f_val; \ _set_->alloc = alloc; \ _set_->callbacks = callbacks; \ @@ -275,16 +292,16 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return _set_; \ } \ \ - void PFX##_clear(struct SNAME *_set_) \ + void CMC_(PFX, _clear)(struct SNAME * _set_) \ { \ - struct SNAME##_node *scan = _set_->root; \ - struct SNAME##_node *up = NULL; \ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ + struct CMC_DEF_NODE(SNAME) *up = NULL; \ \ while (scan != NULL) \ { \ if (scan->left != NULL) \ { \ - struct SNAME##_node *left = scan->left; \ + struct CMC_DEF_NODE(SNAME) *left = scan->left; \ \ scan->left = up; \ up = scan; \ @@ -292,7 +309,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " } \ else if (scan->right != NULL) \ { \ - struct SNAME##_node *right = scan->right; \ + struct CMC_DEF_NODE(SNAME) *right = scan->right; \ \ scan->left = up; \ scan->right = NULL; \ @@ -334,18 +351,19 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " \ _set_->count = 0; \ _set_->root = NULL; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ } \ \ - void PFX##_free(struct SNAME *_set_) \ + void CMC_(PFX, _free)(struct SNAME * _set_) \ { \ - PFX##_clear(_set_); \ + CMC_(PFX, _clear)(_set_); \ \ _set_->alloc->free(_set_); \ } \ \ - void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks) \ + void CMC_(PFX, _customize)(struct SNAME * _set_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ { \ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ @@ -354,25 +372,25 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " \ _set_->callbacks = callbacks; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ } \ \ - bool PFX##_insert(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->root = PFX##_impl_new_node(_set_, value); \ + _set_->root = CMC_(PFX, _impl_new_node)(_set_, value); \ \ if (!_set_->root) \ { \ - _set_->flag = cmc_flags.ALLOC; \ + _set_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ } \ else \ { \ - struct SNAME##_node *scan = _set_->root; \ - struct SNAME##_node *parent = scan; \ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ + struct CMC_DEF_NODE(SNAME) *parent = scan; \ \ while (scan != NULL) \ { \ @@ -384,20 +402,20 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " scan = scan->right; \ else \ { \ - _set_->flag = cmc_flags.DUPLICATE; \ + _set_->flag = CMC_FLAG_DUPLICATE; \ return false; \ } \ } \ \ - struct SNAME##_node *node; \ + struct CMC_DEF_NODE(SNAME) * node; \ \ if (_set_->f_val->cmp(parent->value, value) > 0) \ { \ - parent->left = PFX##_impl_new_node(_set_, value); \ + parent->left = CMC_(PFX, _impl_new_node)(_set_, value); \ \ if (!parent->left) \ { \ - _set_->flag = cmc_flags.ALLOC; \ + _set_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -406,11 +424,11 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " } \ else \ { \ - parent->right = PFX##_impl_new_node(_set_, value); \ + parent->right = CMC_(PFX, _impl_new_node)(_set_, value); \ \ if (!parent->right) \ { \ - _set_->flag = cmc_flags.ALLOC; \ + _set_->flag = CMC_FLAG_ALLOC; \ return false; \ } \ \ @@ -418,11 +436,11 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " node = parent->right; \ } \ \ - PFX##_impl_rebalance(_set_, node); \ + CMC_(PFX, _impl_rebalance)(_set_, node); \ } \ \ _set_->count++; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->create) \ _set_->callbacks->create(); \ @@ -430,23 +448,24 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_remove(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *node = PFX##_impl_get_node(_set_, value); \ + struct CMC_DEF_NODE(SNAME) *node = \ + CMC_(PFX, _impl_get_node)(_set_, value); \ \ if (!node) \ { \ - _set_->flag = cmc_flags.NOT_FOUND; \ + _set_->flag = CMC_FLAG_NOT_FOUND; \ return false; \ } \ \ - struct SNAME##_node *temp = NULL, *unbalanced = NULL; \ + struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \ \ bool is_root = node->parent == NULL; \ \ @@ -550,13 +569,13 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " } \ \ if (unbalanced != NULL) \ - PFX##_impl_rebalance(_set_, unbalanced); \ + CMC_(PFX, _impl_rebalance)(_set_, unbalanced); \ \ if (_set_->count == 0) \ _set_->root = NULL; \ \ _set_->count--; \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->delete) \ _set_->callbacks->delete (); \ @@ -564,15 +583,15 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_max(struct SNAME *_set_, V *value) \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *scan = _set_->root; \ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ \ while (scan->right != NULL) \ scan = scan->right; \ @@ -580,7 +599,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " if (value) \ *value = scan->value; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -588,15 +607,15 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_min(struct SNAME *_set_, V *value) \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ { \ - if (PFX##_empty(_set_)) \ + if (CMC_(PFX, _empty)(_set_)) \ { \ - _set_->flag = cmc_flags.EMPTY; \ + _set_->flag = CMC_FLAG_EMPTY; \ return false; \ } \ \ - struct SNAME##_node *scan = _set_->root; \ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ \ while (scan->left != NULL) \ scan = scan->left; \ @@ -604,7 +623,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " if (value) \ *value = scan->value; \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -612,9 +631,9 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return true; \ } \ \ - bool PFX##_contains(struct SNAME *_set_, V value) \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ { \ - bool result = PFX##_impl_get_node(_set_, value) != NULL; \ + bool result = CMC_(PFX, _impl_get_node)(_set_, value) != NULL; \ \ if (_set_->callbacks && _set_->callbacks->read) \ _set_->callbacks->read(); \ @@ -622,85 +641,88 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return result; \ } \ \ - bool PFX##_empty(struct SNAME *_set_) \ + bool CMC_(PFX, _empty)(struct SNAME * _set_) \ { \ return _set_->count == 0; \ } \ \ - size_t PFX##_count(struct SNAME *_set_) \ + size_t CMC_(PFX, _count)(struct SNAME * _set_) \ { \ return _set_->count; \ } \ \ - int PFX##_flag(struct SNAME *_set_) \ + int CMC_(PFX, _flag)(struct SNAME * _set_) \ { \ return _set_->flag; \ } \ \ - struct SNAME *PFX##_copy_of(struct SNAME *_set_) \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ { \ - struct SNAME *result = \ - PFX##_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks); \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _set_->f_val, _set_->alloc, _set_->callbacks); \ \ if (!result) \ { \ - _set_->flag = cmc_flags.ERROR; \ + _set_->flag = CMC_FLAG_ERROR; \ return NULL; \ } \ \ - if (!PFX##_empty(_set_)) \ + if (!CMC_(PFX, _empty)(_set_)) \ { \ - struct SNAME##_iter iter = PFX##_iter_start(_set_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); \ + CMC_(PFX, _iter_next)(&iter)) \ { \ if (_set_->f_val->cpy) \ - PFX##_insert(result, \ - _set_->f_val->cpy(PFX##_iter_value(&iter))); \ + CMC_(PFX, _insert) \ + (result, \ + _set_->f_val->cpy(CMC_(PFX, _iter_value)(&iter))); \ else \ - PFX##_insert(result, PFX##_iter_value(&iter)); \ + CMC_(PFX, _insert)(result, CMC_(PFX, _iter_value)(&iter)); \ } \ } \ \ - _set_->flag = cmc_flags.OK; \ + _set_->flag = CMC_FLAG_OK; \ \ return result; \ } \ \ - bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ - _set1_->flag = cmc_flags.OK; \ - _set2_->flag = cmc_flags.OK; \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ \ if (_set1_->count != _set2_->count) \ return false; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - if (PFX##_impl_get_node(_set2_, PFX##_iter_value(&iter)) == NULL) \ + if (CMC_(PFX, _impl_get_node)( \ + _set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ return false; \ } \ \ return true; \ } \ \ - struct cmc_string PFX##_to_string(struct SNAME *_set_) \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \ { \ struct cmc_string str; \ struct SNAME *s_ = _set_; \ \ - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_treeset, \ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treeset, \ #SNAME, #V, s_, s_->root, s_->count, s_->flag, \ s_->f_val, s_->alloc, s_->callbacks); \ \ return n >= 0 ? str : (struct cmc_string){ 0 }; \ } \ \ - bool PFX##_print(struct SNAME *_set_, FILE *fptr) \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \ { \ - struct SNAME##_node *root = _set_->root; \ + struct CMC_DEF_NODE(SNAME) *root = _set_->root; \ \ bool left_done = false; \ \ @@ -739,35 +761,38 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return true; \ } \ \ - struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)( \ + _set1_->f_val, _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ \ - struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \ - struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ \ - for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ { \ - PFX##_insert(_set_r_, PFX##_iter_value(&iter1)); \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ } \ \ - for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ { \ - PFX##_insert(_set_r_, PFX##_iter_value(&iter2)); \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ } \ \ return _set_r_; \ } \ \ - struct SNAME *PFX##_intersection(struct SNAME *_set1_, \ - struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)( \ + _set1_->f_val, _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ @@ -777,66 +802,69 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " _set1_->count < _set2_->count ? _set1_ : _set2_; \ struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set_A_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_node(_set_B_, value) != NULL) \ - PFX##_insert(_set_r_, value); \ + if (CMC_(PFX, _impl_get_node)(_set_B_, value) != NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ } \ \ return _set_r_; \ } \ \ - struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)( \ + _set1_->f_val, _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_node(_set2_, value) == NULL) \ - PFX##_insert(_set_r_, value); \ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ } \ \ return _set_r_; \ } \ \ - struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \ - struct SNAME *_set2_) \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - struct SNAME *_set_r_ = \ - PFX##_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)( \ + _set1_->f_val, _set1_->alloc, _set1_->callbacks); \ \ if (!_set_r_) \ return NULL; \ \ - struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \ - struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ \ - for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ { \ - V value = PFX##_iter_value(&iter1); \ + V value = CMC_(PFX, _iter_value)(&iter1); \ \ - if (PFX##_impl_get_node(_set2_, value) == NULL) \ - PFX##_insert(_set_r_, value); \ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ } \ \ - for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ { \ - V value = PFX##_iter_value(&iter2); \ + V value = CMC_(PFX, _iter_value)(&iter2); \ \ - if (PFX##_impl_get_node(_set1_, value) == NULL) \ - PFX##_insert(_set_r_, value); \ + if (CMC_(PFX, _impl_get_node)(_set1_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ } \ \ return _set_r_; \ @@ -845,7 +873,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " /* Is _set1_ a subset of _set2_ ? */ \ /* A set X is a subset of a set Y when: X <= Y */ \ /* If X is a subset of Y, then Y is a superset of X */ \ - bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ /* If the cardinality of _set1_ is greater than that of _set2_ */ \ /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ @@ -853,16 +881,16 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return false; \ \ /* The empty set is a subset of all sets */ \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ return true; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_node(_set2_, value) == NULL) \ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ return false; \ } \ \ @@ -872,15 +900,16 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " /* Is _set1_ a superset of _set2_ ? */ \ /* A set X is a superset of a set Y when: X >= Y */ \ /* If X is a superset of Y, then Y is a subset of X */ \ - bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ - return PFX##_is_subset(_set2_, _set1_); \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ } \ \ /* Is _set1_ a proper subset of _set2_ ? */ \ /* A set X is a proper subset of a set Y when: X < Y */ \ /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* If the cardinality of _set1_ is greater than or equal to that */ \ /* of _set2_, then it is safe to say that _set1_ can't be a proper */ \ @@ -888,10 +917,10 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " if (_set1_->count >= _set2_->count) \ return false; \ \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ { \ /* The empty set is a proper subset of all non-empty sets */ \ - if (!PFX##_empty(_set2_)) \ + if (!CMC_(PFX, _empty)(_set2_)) \ return true; \ /* The empty set is not a proper subset of itself (this is true */ \ /* for any set) */ \ @@ -899,13 +928,13 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return false; \ } \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_node(_set2_, value) == NULL) \ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ return false; \ } \ \ @@ -915,37 +944,39 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " /* Is _set1_ a proper superset of _set2_ ? */ \ /* A set X is a proper superset of a set Y when: X > Y */ \ /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ - return PFX##_is_proper_subset(_set2_, _set1_); \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ } \ \ /* Is _set1_ a disjointset of _set2_ ? */ \ /* A set X is a disjointset of a set Y if their intersection is empty, */ \ /* that is, if there are no elements in common between the two */ \ - bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_) \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ { \ /* The intersection of an empty set with any other set will result */ \ /* in an empty set */ \ - if (PFX##_empty(_set1_)) \ + if (CMC_(PFX, _empty)(_set1_)) \ return true; \ \ - struct SNAME##_iter iter = PFX##_iter_start(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ \ - for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ { \ - V value = PFX##_iter_value(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ \ - if (PFX##_impl_get_node(_set2_, value) != NULL) \ + if (CMC_(PFX, _impl_get_node)(_set2_, value) != NULL) \ return false; \ } \ \ return true; \ } \ \ - struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = target->root; \ @@ -953,9 +984,9 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " iter.last = NULL; \ iter.index = 0; \ iter.start = true; \ - iter.end = PFX##_empty(target); \ + iter.end = CMC_(PFX, _empty)(target); \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ while (iter.cursor->left != NULL) \ iter.cursor = iter.cursor->left; \ @@ -970,19 +1001,19 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return iter; \ } \ \ - struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ { \ - struct SNAME##_iter iter; \ + struct CMC_DEF_ITER(SNAME) iter; \ \ iter.target = target; \ iter.cursor = target->root; \ iter.first = NULL; \ iter.last = NULL; \ iter.index = 0; \ - iter.start = PFX##_empty(target); \ + iter.start = CMC_(PFX, _empty)(target); \ iter.end = true; \ \ - if (!PFX##_empty(target)) \ + if (!CMC_(PFX, _empty)(target)) \ { \ while (iter.cursor->right != NULL) \ iter.cursor = iter.cursor->right; \ @@ -999,23 +1030,23 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return iter; \ } \ \ - bool PFX##_iter_at_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->start; \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ } \ \ - bool PFX##_iter_at_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - return PFX##_empty(iter->target) || iter->end; \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ } \ \ - bool PFX##_iter_to_start(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->index = 0; \ iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ iter->cursor = iter->first; \ \ return true; \ @@ -1024,12 +1055,12 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_to_end(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (!PFX##_empty(iter->target)) \ + if (!CMC_(PFX, _empty)(iter->target)) \ { \ iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ iter->end = true; \ iter->cursor = iter->last; \ \ @@ -1039,7 +1070,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return false; \ } \ \ - bool PFX##_iter_next(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->end) \ return false; \ @@ -1050,7 +1081,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return false; \ } \ \ - iter->start = PFX##_empty(iter->target); \ + iter->start = CMC_(PFX, _empty)(iter->target); \ \ if (iter->cursor->right != NULL) \ { \ @@ -1079,7 +1110,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " } \ } \ \ - bool PFX##_iter_prev(struct SNAME##_iter *iter) \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ if (iter->start) \ return false; \ @@ -1090,7 +1121,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return false; \ } \ \ - iter->end = PFX##_empty(iter->target); \ + iter->end = CMC_(PFX, _empty)(iter->target); \ \ if (iter->cursor->left != NULL) \ { \ @@ -1120,7 +1151,8 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->end) \ return false; \ @@ -1135,13 +1167,14 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_next(iter); \ + CMC_(PFX, _iter_next)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator moved */ \ - bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ { \ if (iter->start) \ return false; \ @@ -1156,44 +1189,45 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return false; \ \ for (size_t i = 0; i < steps; i++) \ - PFX##_iter_prev(iter); \ + CMC_(PFX, _iter_prev)(iter); \ \ return true; \ } \ \ /* Returns true only if the iterator was able to be positioned at the */ \ /* given index */ \ - bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ { \ if (index >= iter->target->count) \ return false; \ \ if (iter->index > index) \ - return PFX##_iter_rewind(iter, iter->index - index); \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ else if (iter->index < index) \ - return PFX##_iter_advance(iter, index - iter->index); \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ \ return true; \ } \ \ - V PFX##_iter_value(struct SNAME##_iter *iter) \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ - if (PFX##_empty(iter->target)) \ + if (CMC_(PFX, _empty)(iter->target)) \ return (V){ 0 }; \ \ return iter->cursor->value; \ } \ \ - size_t PFX##_iter_index(struct SNAME##_iter *iter) \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ { \ return iter->index; \ } \ \ - static struct SNAME##_node *PFX##_impl_new_node(struct SNAME *_set_, \ - V value) \ + static struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value) \ { \ - struct SNAME##_node *node = \ - _set_->alloc->malloc(sizeof(struct SNAME##_node)); \ + struct CMC_DEF_NODE(SNAME) *node = \ + _set_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ \ if (!node) \ return NULL; \ @@ -1207,10 +1241,10 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return node; \ } \ \ - static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_set_, \ - V value) \ + static struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value) \ { \ - struct SNAME##_node *scan = _set_->root; \ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ \ while (scan != NULL) \ { \ @@ -1225,7 +1259,7 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return NULL; \ } \ \ - static unsigned char PFX##_impl_h(struct SNAME##_node *node) \ + static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node) \ { \ if (node == NULL) \ return 0; \ @@ -1233,21 +1267,22 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " return node->height; \ } \ \ - static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node) \ + static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * \ + node) \ { \ if (node == NULL) \ return 0; \ \ - unsigned char h_l = PFX##_impl_h(node->left); \ - unsigned char h_r = PFX##_impl_h(node->right); \ + unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \ + unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \ \ return 1 + (h_l > h_r ? h_l : h_r); \ } \ \ - static void PFX##_impl_rotate_right(struct SNAME##_node **Z) \ + static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z) \ { \ - struct SNAME##_node *root = *Z; \ - struct SNAME##_node *new_root = root->left; \ + struct CMC_DEF_NODE(SNAME) *root = *Z; \ + struct CMC_DEF_NODE(SNAME) *new_root = root->left; \ \ if (root->parent != NULL) \ { \ @@ -1267,16 +1302,16 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " \ new_root->right = root; \ \ - root->height = PFX##_impl_hupdate(root); \ - new_root->height = PFX##_impl_hupdate(new_root); \ + root->height = CMC_(PFX, _impl_hupdate)(root); \ + new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ \ *Z = new_root; \ } \ \ - static void PFX##_impl_rotate_left(struct SNAME##_node **Z) \ + static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \ { \ - struct SNAME##_node *root = *Z; \ - struct SNAME##_node *new_root = root->right; \ + struct CMC_DEF_NODE(SNAME) *root = *Z; \ + struct CMC_DEF_NODE(SNAME) *new_root = root->right; \ \ if (root->parent != NULL) \ { \ @@ -1296,16 +1331,16 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " \ new_root->left = root; \ \ - root->height = PFX##_impl_hupdate(root); \ - new_root->height = PFX##_impl_hupdate(new_root); \ + root->height = CMC_(PFX, _impl_hupdate)(root); \ + new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ \ *Z = new_root; \ } \ \ - static void PFX##_impl_rebalance(struct SNAME *_set_, \ - struct SNAME##_node *node) \ + static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, \ + struct CMC_DEF_NODE(SNAME) * node) \ { \ - struct SNAME##_node *scan = node, *child = NULL; \ + struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \ \ int balance; \ bool is_root = false; \ @@ -1315,26 +1350,29 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " if (scan->parent == NULL) \ is_root = true; \ \ - scan->height = PFX##_impl_hupdate(scan); \ - balance = PFX##_impl_h(scan->right) - PFX##_impl_h(scan->left); \ + scan->height = CMC_(PFX, _impl_hupdate)(scan); \ + balance = CMC_(PFX, _impl_h)(scan->right) - \ + CMC_(PFX, _impl_h)(scan->left); \ \ if (balance >= 2) \ { \ child = scan->right; \ \ - if (PFX##_impl_h(child->right) < PFX##_impl_h(child->left)) \ - PFX##_impl_rotate_right(&(scan->right)); \ + if (CMC_(PFX, _impl_h)(child->right) < \ + CMC_(PFX, _impl_h)(child->left)) \ + CMC_(PFX, _impl_rotate_right)(&(scan->right)); \ \ - PFX##_impl_rotate_left(&scan); \ + CMC_(PFX, _impl_rotate_left)(&scan); \ } \ else if (balance <= -2) \ { \ child = scan->left; \ \ - if (PFX##_impl_h(child->left) < PFX##_impl_h(child->right)) \ - PFX##_impl_rotate_left(&(scan->left)); \ + if (CMC_(PFX, _impl_h)(child->left) < \ + CMC_(PFX, _impl_h)(child->right)) \ + CMC_(PFX, _impl_rotate_left)(&(scan->left)); \ \ - PFX##_impl_rotate_right(&scan); \ + CMC_(PFX, _impl_rotate_right)(&scan); \ } \ \ if (is_root) \ @@ -1347,4 +1385,4 @@ static const char *cmc_string_fmt_treeset = "struct %s<%s> " } \ } -#endif /* CMC_TREESET_H */ +#endif /* CMC_CMC_TREESET_H */ diff --git a/src/cor/alloc.h b/src/cor/alloc.h index 734c34e..a8dc362 100644 --- a/src/cor/alloc.h +++ b/src/cor/alloc.h @@ -17,7 +17,8 @@ * struct cmc_alloc_node * * Custom allocation node. Allows collections to use custom allocation - * functions. + * functions. The cmc_alloc_node_default is the default heap allocator provided + * by the standard library. */ static struct cmc_alloc_node { diff --git a/src/cor/core.h b/src/cor/core.h index e63219b..36d0bd9 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -9,13 +9,7 @@ */ /** - * Core includes and structs used in the library. - * - * In here you will find: - * struct cmc_string - * struct cmc_alloc_node - * struct cmc_callbacks - * cmc_flags + * Core includes and macros for the entire library. */ #ifndef CMC_COR_CORE_H @@ -31,10 +25,34 @@ #include "alloc.h" #include "callbacks.h" #include "flags.h" +#include "params.h" + +#define CMC__(A, B) A##B +#define CMC_(A, B) CMC__(A, B) #define CMC_TO_STRING_(X) #X #define CMC_TO_STRING(X) CMC_TO_STRING_(X) +#if defined(CMC_CAMEL_CASE) +#define CMC_INTERNAL_PREFIX_ITER Iter +#define CMC_INTERNAL_PREFIX_NODE Node +#define CMC_INTERNAL_PREFIX_ENTRY Entry +#define CMC_INTERNAL_PREFIX_FVAL FVal +#define CMC_INTERNAL_PREFIX_FKEY FKey +#else +#define CMC_INTERNAL_PREFIX_ITER _iter +#define CMC_INTERNAL_PREFIX_NODE _node +#define CMC_INTERNAL_PREFIX_ENTRY _entry +#define CMC_INTERNAL_PREFIX_FVAL _fval +#define CMC_INTERNAL_PREFIX_FKEY _fkey +#endif + +#define CMC_DEF_ITER(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_ITER) +#define CMC_DEF_NODE(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_NODE) +#define CMC_DEF_ENTRY(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_ENTRY) +#define CMC_DEF_FVAL(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FVAL) +#define CMC_DEF_FKEY(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FKEY) + /** * struct cmc_string * diff --git a/src/cor/flags.h b/src/cor/flags.h index e007623..3f06034 100644 --- a/src/cor/flags.h +++ b/src/cor/flags.h @@ -12,23 +12,25 @@ #define CMC_COR_FLAGS_H /** - * cmc_flags + * enum cmc_flags * * Defines common error codes used by the entire library. */ -static struct +// clang-format off +enum cmc_flags { - int OK; // No errors - int ALLOC; // Allocation failed - int EMPTY; // The collection is empty when it should not - int NOT_FOUND; // Key or value not found - int INVALID; // Invalid argument or operation - int RANGE; // Index out of range - int DUPLICATE; // Duplicate key or value - int ERROR; // Generic error, usually caused by algorithm error - int THREAD; // Generic error regarding threads - int MUTEX; // Generic error regarding mutexes -} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + CMC_FLAG_OK = 0, // No errors + CMC_FLAG_ALLOC = 2, // Allocation failed + CMC_FLAG_EMPTY = 3, // The collection is empty when it should not + CMC_FLAG_NOT_FOUND = 4, // Key or value not found + CMC_FLAG_INVALID = 5, // Invalid argument or operation + CMC_FLAG_RANGE = 6, // Index out of range + CMC_FLAG_DUPLICATE = 7, // Duplicate key or value + CMC_FLAG_ERROR = 8, // Generic error, usually caused by algorithm error + CMC_FLAG_THREAD = 9, // Generic error regarding threads + CMC_FLAG_MUTEX = 10 // Generic error regarding mutexes +}; +// clang-format on /** * cmc_flags_to_str diff --git a/src/dev/deque.h b/src/dev/deque.h deleted file mode 100644 index 85841a3..0000000 --- a/src/dev/deque.h +++ /dev/null @@ -1,654 +0,0 @@ -/** - * deque.h - * - * Creation Date: 21/06/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/*****************************************************************************/ -/********************************************************************* DEQUE */ -/*****************************************************************************/ - -#ifndef CMC_DEQUE_H -#define CMC_DEQUE_H - -#include -#include -#include -#include -#include -#include "utl/log.h" - -#define DEQUE_GENERATE(PFX, SNAME, FMOD, V) \ - DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \ - DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) - -#define DEQUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \ - DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) - -#define DEQUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \ - DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) - -/* HEADER ********************************************************************/ -#define DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \ - \ - /* Deque Structure */ \ - typedef struct SNAME##_s \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ - \ - /* Current circular array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Index representing the front of the deque */ \ - size_t front; \ - \ - /* Index representing the back of the deque */ \ - size_t back; \ - \ - /* Function that returns an iterator to the start of the deque */ \ - struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \ - \ - /* Function that returns an iterator to the end of the deque */ \ - struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \ - \ - } SNAME, *SNAME##_ptr; \ - \ - /* Deque Iterator */ \ - typedef struct SNAME##_iter_s \ - { \ - /* Target deque */ \ - struct SNAME##_s *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - \ - } SNAME##_iter, *SNAME##_iter_ptr; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - FMOD SNAME *PFX##_new(size_t capacity); \ - FMOD void PFX##_clear(SNAME *_deque_); \ - FMOD void PFX##_free(SNAME *_deque_); \ - /* Collection Input and Output */ \ - FMOD bool PFX##_push_front(SNAME *_deque_, V element); \ - FMOD bool PFX##_push_back(SNAME *_deque_, V element); \ - FMOD bool PFX##_pop_front(SNAME *_deque_); \ - FMOD bool PFX##_pop_back(SNAME *_deque_); \ - /* Conditional Input and Output */ \ - FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition); \ - FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition); \ - FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition); \ - FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition); \ - /* Element Access */ \ - FMOD V PFX##_front(SNAME *_deque_); \ - FMOD V PFX##_back(SNAME *_deque_); \ - /* Collection State */ \ - FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)); \ - FMOD bool PFX##_empty(SNAME *_deque_); \ - FMOD bool PFX##_full(SNAME *_deque_); \ - FMOD size_t PFX##_count(SNAME *_deque_); \ - FMOD size_t PFX##_capacity(SNAME *_deque_); \ - \ - /* Iterator Functions */ \ - /* Iterator Allocation and Deallocation */ \ - FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \ - FMOD void PFX##_iter_free(SNAME##_iter *iter); \ - /* Iterator Initialization */ \ - FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \ - /* Iterator State */ \ - FMOD bool PFX##_iter_start(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_end(SNAME##_iter *iter); \ - /* Iterator Movement */ \ - FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \ - FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_next(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \ - /* Iterator Access */ \ - FMOD V PFX##_iter_value(SNAME##_iter *iter); \ - FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \ - FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \ - \ - /* Default Value */ \ - static inline V PFX##_impl_default_value(void) \ - { \ - V _empty_value_; \ - \ - memset(&_empty_value_, 0, sizeof(V)); \ - \ - return _empty_value_; \ - } \ - \ -/* SOURCE ********************************************************************/ -#define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \ - \ - /* Implementation Detail Functions */ \ - static bool PFX##_impl_grow(SNAME *_deque_); \ - static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \ - static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \ - \ - FMOD SNAME *PFX##_new(size_t capacity) \ - { \ - if (capacity < 1) \ - { \ - log_warn("Invalid capacity for %s given: %s", "Heap", capacity); \ - return NULL; \ - } \ - \ - SNAME *_deque_ = malloc(sizeof(SNAME)); \ - \ - if (!_deque_) \ - { \ - log_info("%s allocation failed", "Deque"); \ - return NULL; \ - } \ - \ - _deque_->buffer = malloc(sizeof(V) * capacity); \ - \ - if (!_deque_->buffer) \ - { \ - log_info("%s allocation failed", "Deque buffer"); \ - free(_deque_); \ - return NULL; \ - } \ - \ - memset(_deque_->buffer, 0, sizeof(V) * capacity); \ - \ - _deque_->capacity = capacity; \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - \ - _deque_->it_start = PFX##_impl_it_start; \ - _deque_->it_end = PFX##_impl_it_end; \ - \ - log_info("Deque at %p successfully allocated", _deque_); \ - \ - return _deque_; \ - } \ - \ - FMOD void PFX##_clear(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \ - \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - \ - log_trace("Deque at %p cleared", _deque_); \ - } \ - \ - FMOD void PFX##_free(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - free(_deque_->buffer); \ - \ - uintptr_t address = (uintptr_t)(void *)_deque_; \ - \ - free(_deque_); \ - \ - log_info("Heap at %p successfully deallocated", address); \ - } \ - \ - FMOD bool PFX##_push_front(SNAME *_deque_, V element) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - if (PFX##_full(_deque_)) \ - { \ - if (!PFX##_impl_grow(_deque_)) \ - { \ - log_info("Deque at %p failed to be reallocated", _deque_); \ - return false; \ - } \ - } \ - \ - _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \ - \ - _deque_->buffer[_deque_->front] = element; \ - \ - log_trace("Element added at %" PRIuMAX " to Deque at %p", _deque_->front, _deque_); \ - \ - _deque_->count++; \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_push_back(SNAME *_deque_, V element) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - if (PFX##_full(_deque_)) \ - { \ - if (!PFX##_impl_grow(_deque_)) \ - { \ - log_info("Deque at %p failed to be reallocated", _deque_); \ - return false; \ - } \ - } \ - \ - _deque_->buffer[_deque_->back] = element; \ - \ - log_trace("Element added at %" PRIuMAX " to Deque at %p", _deque_->back, _deque_); \ - \ - _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ - \ - _deque_->count++; \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_pop_front(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - if (PFX##_empty(_deque_)) \ - { \ - log_debug("Attempt of removing an element from empty Deque at %p", _deque_); \ - \ - return false; \ - } \ - \ - _deque_->buffer[_deque_->front] = PFX##_impl_default_value(); \ - \ - log_trace("Element removed from %" PRIuMAX " to Deque at %p", _deque_->front, _deque_); \ - \ - _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \ - \ - _deque_->count--; \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_pop_back(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - { \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - } \ - \ - if (PFX##_empty(_deque_)) \ - { \ - log_debug("Attempt of removing an element from empty Deque at %p", _deque_); \ - \ - return false; \ - } \ - \ - _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ - \ - _deque_->buffer[_deque_->back] = PFX##_impl_default_value(); \ - \ - log_trace("Element removed from %" PRIuMAX " to Deque at %p", _deque_->back, _deque_); \ - \ - _deque_->count--; \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \ - { \ - if (condition) \ - return PFX##_push_front(_deque_, element); \ - \ - return false; \ - } \ - \ - FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \ - { \ - if (condition) \ - return PFX##_push_back(_deque_, element); \ - \ - return false; \ - } \ - \ - FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \ - { \ - if (condition) \ - return PFX##_pop_front(_deque_); \ - \ - return false; \ - } \ - \ - FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \ - { \ - if (condition) \ - return PFX##_pop_back(_deque_); \ - \ - return false; \ - } \ - \ - FMOD V PFX##_front(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - if (PFX##_empty(_deque_)) \ - { \ - log_debug("Attempt to access element from empty Deque at %p", _deque_); \ - \ - PFX##_impl_default_value(); \ - } \ - \ - log_trace("Element access at %" PRIuMAX "", _deque_->front); \ - \ - return _deque_->buffer[_deque_->front]; \ - } \ - \ - FMOD V PFX##_back(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - if (PFX##_empty(_deque_)) \ - { \ - log_debug("Attempt to access element from empty Deque at %p", _deque_); \ - \ - PFX##_impl_default_value(); \ - } \ - \ - size_t index = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ - \ - log_trace("Element access at %" PRIuMAX "", index); \ - \ - return _deque_->buffer[index]; \ - } \ - \ - FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - if (comparator == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "comparator"); \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++) \ - { \ - if (comparator(_deque_->buffer[i], element) == 0) \ - return true; \ - } \ - \ - return false; \ - } \ - \ - FMOD bool PFX##_empty(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - return _deque_->count == 0; \ - } \ - \ - FMOD bool PFX##_full(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - return _deque_->count >= _deque_->capacity; \ - } \ - \ - FMOD size_t PFX##_count(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - return _deque_->count; \ - } \ - \ - FMOD size_t PFX##_capacity(SNAME *_deque_) \ - { \ - if (_deque_ == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "_deque_"); \ - \ - return _deque_->capacity; \ - } \ - \ - FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \ - { \ - SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \ - \ - if (!iter) \ - { \ - log_info("%s allocation failed", "Deque Iterator"); \ - return NULL; \ - } \ - \ - PFX##_iter_init(iter, target); \ - \ - log_info("Deque Iterator allocated at %p referencing Heap at %p", iter, target); \ - \ - return iter; \ - } \ - \ - FMOD void PFX##_iter_free(SNAME##_iter *iter) \ - { \ - uintptr_t address = (uintptr_t)(void *)iter; \ - \ - free(iter); \ - \ - log_info("Deque Iterator deallocated at %" PRIxPTR "", address); \ - } \ - \ - FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \ - { \ - if (target == NULL) \ - log_fatal("Heap Iterator at %p initialized with null pointer target", iter); \ - \ - if (PFX##_empty(target)) \ - log_warn("Deque Iterator at %p initialized with empty target", iter); \ - \ - iter->target = target; \ - iter->cursor = target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(target); \ - } \ - \ - FMOD bool PFX##_iter_start(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - return PFX##_empty(iter->target) || iter->start; \ - } \ - \ - FMOD bool PFX##_iter_end(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - return PFX##_empty(iter->target) || iter->end; \ - } \ - \ - FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ - \ - log_trace("Deque Iterator at %p with cursor at %" PRIuMAX "", iter, iter->cursor); \ - } \ - \ - FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - if (PFX##_empty(iter->target)) \ - iter->cursor = 0; \ - else \ - iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1; \ - \ - iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ - iter->end = true; \ - \ - log_trace("Deque Iterator at %p with cursor at %" PRIuMAX "", iter, iter->cursor); \ - } \ - \ - FMOD bool PFX##_iter_next(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - if (iter->end) \ - return false; \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - if (iter->index == iter->target->count - 1) \ - { \ - log_trace("Deque Iterator at %p reached the end of Deque %p", iter, iter->target); \ - iter->end = true; \ - } \ - else \ - { \ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ - \ - log_trace("Deque Iterator at %p moved to %" PRIuMAX "", iter, iter->cursor); \ - } \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - if (iter->start) \ - return false; \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - if (iter->index == 0) \ - { \ - log_trace("Deque Iterator at %p reached the start of Deque %p", iter, iter->target); \ - iter->start = true; \ - } \ - else \ - { \ - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \ - iter->index--; \ - \ - log_trace("Deque Iterator at %p moved to %" PRIuMAX "", iter, iter->cursor); \ - } \ - \ - return true; \ - } \ - \ - FMOD V PFX##_iter_value(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - if (PFX##_empty(iter->target)) \ - { \ - log_debug("Attempt to access element from iterator %p with empty target %p", iter, iter->target); \ - PFX##_impl_default_value(); \ - } \ - \ - log_trace("Element access at %" PRIuMAX "", iter->cursor); \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - if (PFX##_empty(iter->target)) \ - { \ - log_debug("Attempt to access element from iterator %p with empty target %p", iter, iter->target); \ - return NULL; \ - } \ - \ - log_trace("Element access at %" PRIuMAX "", iter->cursor); \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \ - { \ - if (iter == NULL) \ - log_fatal("Invalid null pointer parameter: %s", "iter"); \ - \ - return iter->index; \ - } \ - \ - static bool PFX##_impl_grow(SNAME *_deque_) \ - { \ - size_t new_capacity = _deque_->capacity * 2; \ - \ - V *new_buffer = malloc(sizeof(V) * new_capacity); \ - \ - if (!new_buffer) \ - { \ - log_info("%s reallocation failed", "Deque buffer"); \ - return false; \ - } \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \ - { \ - new_buffer[j] = _deque_->buffer[i]; \ - } \ - \ - free(_deque_->buffer); \ - \ - _deque_->buffer = new_buffer; \ - _deque_->capacity = new_capacity; \ - _deque_->front = 0; \ - _deque_->back = _deque_->count; \ - \ - return true; \ - } \ - \ - static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \ - { \ - SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _deque_); \ - \ - return iter; \ - } \ - \ - static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \ - { \ - SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _deque_); \ - PFX##_iter_to_end(&iter); \ - \ - return iter; \ - } - -#endif /* CMC_DEQUE_H */ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index cf01c47..72fdeac 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -37,23 +37,25 @@ CMC_EXT_CMC_DEQUE_INIT_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ CMC_PARAM_V(BODY)) -#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ - \ - struct SNAME PFX##_init(size_t capacity, struct SNAME##_fval *f_val); \ - struct SNAME PFX##_init_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ + \ + struct SNAME CMC_(PFX, _init)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME CMC_(PFX, _init_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); #define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ \ - struct SNAME PFX##_init(size_t capacity, struct SNAME##_fval *f_val) \ + struct SNAME CMC_(PFX, _init)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ - return PFX##_init_custom(capacity, f_val, NULL, NULL); \ + return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \ } \ \ - struct SNAME PFX##_init_custom( \ - size_t capacity, struct SNAME##_fval *f_val, \ - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \ + struct SNAME CMC_(PFX, _init_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ { \ struct SNAME _deque_ = { 0 }; \ \ diff --git a/src/ext/cmc/hashbidimap.h b/src/ext/cmc/hashbidimap.h new file mode 100644 index 0000000..e69de29 diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index fde1147..26837d5 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -37,63 +37,65 @@ CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(BODY), \ CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) -#define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(PFX, SNAME, V) \ - \ - struct SNAME PFX##_init(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val); \ - struct SNAME PFX##_init_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \ - struct cmc_callbacks *callbacks); +#define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(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); \ + 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); -#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, V) \ - \ - struct SNAME PFX##_init(size_t capacity, double load, \ - struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *f_val) \ - { \ - return PFX##_init_custom(capacity, load, f_key, f_val, NULL, NULL); \ - } \ - \ - struct SNAME PFX##_init_custom( \ - size_t capacity, double load, struct SNAME##_fkey *f_key, \ - struct SNAME##_fval *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 = 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_flags.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, 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_flags.OK; \ + _map_.f_key = f_key; \ + _map_.f_val = f_val; \ + _map_.alloc = alloc; \ + _map_.callbacks = callbacks; \ + \ + return _map_; \ } #endif /* CMC_EXT_CMC_HASHMAP_H */ diff --git a/src/sac/queue.h b/src/sac/queue.h deleted file mode 100644 index 7567cb7..0000000 --- a/src/sac/queue.h +++ /dev/null @@ -1,357 +0,0 @@ -/** - * queue.h - * - * Creation Date: 24/06/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * A Purely Stack Allocated Queue - * - * This means that the Queue has a fixed size, but it also has the advantage of - * not requiring for manually allocating and deallocating the struct. - * - * Generating a collection with too big of a storage can be dangerous and might - * quickly cause a stack overflow. - * - * It is recommended to not generate any Stack Allocated Collection with less - * than 1000 internal storage. - */ - -#ifndef CMC_SAC_QUEUE_H -#define CMC_SAC_QUEUE_H - -#include -#include -#include - -#define SAC_QUEUE_GENERATE(PFX, SNAME, FMOD, V, SIZE) \ - SAC_QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) \ - SAC_QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE) - -#define SAC_QUEUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V, SIZE) \ - SAC_QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) - -#define SAC_QUEUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V, SIZE) \ - SAC_QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE) - -/* HEADER ********************************************************************/ -#define SAC_QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) \ - \ - /* Queue Structure */ \ - typedef struct SNAME##_s \ - { \ - /* Internal Storage */ \ - V buffer[SIZE]; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Index representing the front of the queue */ \ - size_t front; \ - \ - /* Index representing the back of the queue */ \ - size_t rear; \ - \ - /* Function that returns an iterator to the start of the queue */ \ - struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \ - \ - /* Function that returns an iterator to the end of the queue */ \ - struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \ - \ - } SNAME, *SNAME##_ptr; \ - \ - /* Queue Iterator */ \ - typedef struct SNAME##_iter_s \ - { \ - /* Target queue */ \ - struct SNAME##_s *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - \ - } SNAME##_iter, *SNAME##_iter_ptr; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - FMOD SNAME PFX##_new(void); \ - FMOD void PFX##_clear(SNAME *_queue_); \ - /* Collection Input and Output */ \ - FMOD bool PFX##_enqueue(SNAME *_queue_, V element); \ - FMOD bool PFX##_dequeue(SNAME *_queue_); \ - /* Conditional Input and Output */ \ - FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition); \ - FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition); \ - /* Element Access */ \ - FMOD V PFX##_peek(SNAME *_queue_); \ - /* Collection State */ \ - FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)); \ - FMOD bool PFX##_empty(SNAME *_queue_); \ - FMOD bool PFX##_full(SNAME *_queue_); \ - FMOD size_t PFX##_count(SNAME *_queue_); \ - FMOD size_t PFX##_capacity(void); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \ - /* Iterator State */ \ - FMOD bool PFX##_iter_start(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_end(SNAME##_iter *iter); \ - /* Iterator Movement */ \ - FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \ - FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_next(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \ - /* Iterator Access */ \ - FMOD V PFX##_iter_value(SNAME##_iter *iter); \ - FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \ - FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \ - \ - /* Default Value */ \ - static inline V PFX##_impl_default_value(void) \ - { \ - V _empty_value_; \ - \ - memset(&_empty_value_, 0, sizeof(V)); \ - \ - return _empty_value_; \ - } \ - \ -/* SOURCE ********************************************************************/ -#define SAC_QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE) \ - \ - /* Implementation Detail Functions */ \ - static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \ - static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \ - \ - FMOD SNAME PFX##_new(void) \ - { \ - SNAME result; \ - \ - memset(&result, 0, sizeof(SNAME)); \ - \ - result.it_start = PFX##_impl_it_start; \ - result.it_end = PFX##_impl_it_end; \ - \ - return result; \ - } \ - \ - FMOD void PFX##_clear(SNAME *_queue_) \ - { \ - memset(_queue_->buffer, 0, sizeof(_queue_->buffer)); \ - \ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->rear = 0; \ - } \ - \ - FMOD bool PFX##_enqueue(SNAME *_queue_, V element) \ - { \ - if (PFX##_full(_queue_)) \ - return false; \ - \ - _queue_->buffer[_queue_->rear] = element; \ - \ - _queue_->rear = (_queue_->rear == SIZE - 1) ? 0 : _queue_->rear + 1; \ - _queue_->count++; \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_dequeue(SNAME *_queue_) \ - { \ - if (PFX##_empty(_queue_)) \ - return false; \ - \ - _queue_->buffer[_queue_->front] = PFX##_impl_default_value(); \ - \ - _queue_->front = (_queue_->front == SIZE - 1) ? 0 : _queue_->front + 1; \ - _queue_->count--; \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \ - { \ - if (condition) \ - return PFX##_enqueue(_queue_, element); \ - \ - return false; \ - } \ - \ - FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \ - { \ - if (condition) \ - return PFX##_dequeue(_queue_); \ - \ - return false; \ - } \ - \ - FMOD V PFX##_peek(SNAME *_queue_) \ - { \ - if (PFX##_empty(_queue_)) \ - return PFX##_impl_default_value(); \ - \ - return _queue_->buffer[_queue_->front]; \ - } \ - \ - FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->count, j++) \ - { \ - if (comparator(_queue_->buffer[i], element) == 0) \ - return true; \ - } \ - \ - return false; \ - } \ - \ - FMOD bool PFX##_empty(SNAME *_queue_) \ - { \ - return _queue_->count == 0; \ - } \ - \ - FMOD bool PFX##_full(SNAME *_queue_) \ - { \ - return _queue_->count >= SIZE; \ - } \ - \ - FMOD size_t PFX##_count(SNAME *_queue_) \ - { \ - return _queue_->count; \ - } \ - \ - FMOD size_t PFX##_capacity(void) \ - { \ - return SIZE; \ - } \ - \ - FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \ - { \ - iter->target = target; \ - iter->cursor = target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(target); \ - } \ - \ - FMOD bool PFX##_iter_start(SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->start; \ - } \ - \ - FMOD bool PFX##_iter_end(SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->end; \ - } \ - \ - FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ - } \ - \ - FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - iter->cursor = 0; \ - else \ - iter->cursor = (iter->target->rear == 0) ? SIZE - 1 : iter->target->rear - 1; \ - \ - iter->index = iter->target->count - 1; \ - iter->start = PFX##_empty(iter->target); \ - iter->end = true; \ - } \ - \ - FMOD bool PFX##_iter_next(SNAME##_iter *iter) \ - { \ - if (iter->end) \ - return false; \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - if (iter->index == iter->target->count - 1) \ - iter->end = true; \ - else \ - { \ - iter->cursor = (iter->cursor + 1) % (SIZE); \ - iter->index++; \ - } \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \ - { \ - if (iter->start) \ - return false; \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - if (iter->index == 0) \ - iter->start = true; \ - else \ - { \ - iter->cursor = (iter->cursor == 0) ? SIZE - 1 : iter->cursor - 1; \ - iter->index--; \ - } \ - \ - return true; \ - } \ - \ - FMOD V PFX##_iter_value(SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return PFX##_impl_default_value(); \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \ - { \ - return iter->index; \ - } \ - \ - static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_) \ - { \ - SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _queue_); \ - PFX##_iter_to_start(&iter); \ - \ - return iter; \ - } \ - \ - static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_) \ - { \ - SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _queue_); \ - PFX##_iter_to_end(&iter); \ - \ - return iter; \ - } - -#endif /* CMC_SAC_QUEUE_H */ diff --git a/src/sac/stack.h b/src/sac/stack.h deleted file mode 100644 index 5567e6c..0000000 --- a/src/sac/stack.h +++ /dev/null @@ -1,327 +0,0 @@ -/** - * stack.h - * - * Creation Date: 21/06/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * A Purely Stack Allocated Stack - * - * This means that the Stack has a fixed size, but it also has the advantage of - * not requiring for manually allocating and deallocating the struct. - * - * Generating a collection with too big of a storage can be dangerous and might - * quickly cause a stack overflow. - * - * It is recommended to not generate any Stack Allocated Collection with less - * than 1000 internal storage. - */ - -#ifndef CMC_SAC_STACK_H -#define CMC_SAC_STACK_H - -#include -#include -#include - -#define SAC_STACK_GENERATE(PFX, SNAME, FMOD, V, SIZE) \ - SAC_STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) \ - SAC_STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE) - -#define SAC_STACK_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V, SIZE) \ - SAC_STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) - -#define SAC_STACK_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V, SIZE) \ - SAC_STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE) - -/* HEADER ********************************************************************/ -#define SAC_STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) \ - \ - /* Stack Structure */ \ - typedef struct SNAME##_s \ - { \ - /* Internal Storage */ \ - V buffer[SIZE]; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Function that returns an iterator to the start of the stack */ \ - struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \ - \ - /* Function that returns an iterator to the end of the stack */ \ - struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \ - \ - } SNAME, *SNAME##_ptr; \ - \ - /* Stack Iterator */ \ - typedef struct SNAME##_iter_s \ - { \ - /* Target stack */ \ - struct SNAME##_s *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - \ - } SNAME##_iter, *SNAME##_iter_ptr; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - FMOD SNAME PFX##_new(void); \ - FMOD void PFX##_clear(SNAME *_stack_); \ - /* Collection Input and Output */ \ - FMOD bool PFX##_push(SNAME *_stack_, V element); \ - FMOD bool PFX##_pop(SNAME *_stack_); \ - /* Conditional Input and Output */ \ - FMOD bool PFX##_push_if(SNAME *_stack_, V element, bool condition); \ - FMOD bool PFX##_pop_if(SNAME *_stack_, bool condition); \ - /* Element Access */ \ - FMOD V PFX##_top(SNAME *_stack_); \ - /* Collection State */ \ - FMOD bool PFX##_contains(SNAME *_stack_, V element, int (*comparator)(V, V)); \ - FMOD bool PFX##_empty(SNAME *_stack_); \ - FMOD bool PFX##_full(SNAME *_stack_); \ - FMOD size_t PFX##_count(SNAME *_stack_); \ - FMOD size_t PFX##_capacity(void); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \ - /* Iterator State */ \ - FMOD bool PFX##_iter_start(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_end(SNAME##_iter *iter); \ - /* Iterator Movement */ \ - FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \ - FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_next(SNAME##_iter *iter); \ - FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \ - /* Iterator Access */ \ - FMOD V PFX##_iter_value(SNAME##_iter *iter); \ - FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \ - FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \ - \ - /* Default Value */ \ - static inline V PFX##_impl_default_value(void) \ - { \ - V _empty_value_; \ - \ - memset(&_empty_value_, 0, sizeof(V)); \ - \ - return _empty_value_; \ - } \ - \ -/* SOURCE ********************************************************************/ -#define SAC_STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE) \ - \ - /* Implementation Detail Functions */ \ - static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_); \ - static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_); \ - \ - FMOD SNAME PFX##_new(void) \ - { \ - SNAME result; \ - \ - memset(&result, 0, sizeof(SNAME)); \ - \ - result.it_start = PFX##_impl_it_start; \ - result.it_end = PFX##_impl_it_end; \ - \ - return result; \ - } \ - \ - FMOD void PFX##_clear(SNAME *_stack_) \ - { \ - memset(_stack_->buffer, 0, sizeof(_stack_->buffer)); \ - \ - _stack_->count = 0; \ - } \ - \ - FMOD bool PFX##_push(SNAME *_stack_, V element) \ - { \ - if (PFX##_full(_stack_)) \ - return false; \ - \ - _stack_->buffer[_stack_->count++] = element; \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_pop(SNAME *_stack_) \ - { \ - if (PFX##_empty(_stack_)) \ - return false; \ - \ - _stack_->buffer[--_stack_->count] = PFX##_impl_default_value(); \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_push_if(SNAME *_stack_, V element, bool condition) \ - { \ - if (condition) \ - return PFX##_push(_stack_, element); \ - \ - return false; \ - } \ - \ - FMOD bool PFX##_pop_if(SNAME *_stack_, bool condition) \ - { \ - if (condition) \ - return PFX##_pop(_stack_); \ - \ - return false; \ - } \ - \ - FMOD V PFX##_top(SNAME *_stack_) \ - { \ - if (PFX##_empty(_stack_)) \ - return PFX##_impl_default_value(); \ - \ - return _stack_->buffer[_stack_->count - 1]; \ - } \ - \ - FMOD bool PFX##_contains(SNAME *_stack_, V element, int (*comparator)(V, V)) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - { \ - if (comparator(_stack_->buffer[i], element) == 0) \ - return true; \ - } \ - \ - return false; \ - } \ - \ - FMOD bool PFX##_empty(SNAME *_stack_) \ - { \ - return _stack_->count == 0; \ - } \ - \ - FMOD bool PFX##_full(SNAME *_stack_) \ - { \ - return _stack_->count >= SIZE; \ - } \ - \ - FMOD size_t PFX##_count(SNAME *_stack_) \ - { \ - return _stack_->count; \ - } \ - \ - FMOD size_t PFX##_capacity(void) \ - { \ - return SIZE; \ - } \ - \ - FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \ - { \ - iter->target = target; \ - iter->cursor = iter->target->count - 1; \ - iter->start = true; \ - iter->end = PFX##_empty(target); \ - } \ - \ - FMOD bool PFX##_iter_start(SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->start; \ - } \ - \ - FMOD bool PFX##_iter_end(SNAME##_iter *iter) \ - { \ - return PFX##_empty(iter->target) || iter->end; \ - } \ - \ - FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = true; \ - iter->end = PFX##_empty(iter->target); \ - } \ - \ - FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \ - { \ - iter->cursor = 0; \ - iter->start = PFX##_empty(iter->target); \ - iter->end = true; \ - } \ - \ - FMOD bool PFX##_iter_next(SNAME##_iter *iter) \ - { \ - if (iter->end) \ - return false; \ - \ - iter->start = PFX##_empty(iter->target); \ - \ - if (iter->cursor == 0) \ - iter->end = true; \ - else \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \ - { \ - if (iter->start) \ - return false; \ - \ - iter->end = PFX##_empty(iter->target); \ - \ - if (iter->cursor == iter->target->count - 1) \ - iter->start = true; \ - else \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - FMOD V PFX##_iter_value(SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return PFX##_impl_default_value(); \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \ - { \ - if (PFX##_empty(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \ - { \ - return iter->target->count - 1 - iter->cursor; \ - } \ - \ - static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_) \ - { \ - SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _stack_); \ - PFX##_iter_to_start(&iter); \ - \ - return iter; \ - } \ - \ - static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_) \ - { \ - SNAME##_iter iter; \ - \ - PFX##_iter_init(&iter, _stack_); \ - PFX##_iter_to_end(&iter); \ - \ - return iter; \ - } - -#endif /* CMC_SAC_STACK_H */ diff --git a/src/utl/assert.h b/src/utl/assert.h index 9b0f001..11a8800 100644 --- a/src/utl/assert.h +++ b/src/utl/assert.h @@ -48,8 +48,8 @@ * - cmc_assert_array_sorted_any */ -#ifndef CMC_ASSERT_H -#define CMC_ASSERT_H +#ifndef CMC_UTL_ASSERT_H +#define CMC_UTL_ASSERT_H #include #include @@ -2830,4 +2830,4 @@ static uintmax_t cmc_assert_failed = 0; \ } while (0) -#endif /* CMC_ASSERT_H */ +#endif /* CMC_UTL_ASSERT_H */ diff --git a/src/utl/foreach.h b/src/utl/foreach.h index 207758e..fb6be06 100644 --- a/src/utl/foreach.h +++ b/src/utl/foreach.h @@ -17,15 +17,19 @@ * TARGET - Target variable */ -#ifndef CMC_FOREACH_H -#define CMC_FOREACH_H +#ifndef CMC_UTL_FOREACH_H +#define CMC_UTL_FOREACH_H -#define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \ - for (struct SNAME##_iter ITERNAME = PFX##_iter_start(TARGET); \ - !PFX##_iter_at_end(&ITERNAME); PFX##_iter_next(&ITERNAME)) +#include "../cor/core.h" -#define CMC_FOREACH_REV(PFX, SNAME, ITERNAME, TARGET) \ - for (struct SNAME##_iter ITERNAME = PFX##_iter_end(TARGET); \ - !PFX##_iter_at_start(&ITERNAME); PFX##_iter_prev(&ITERNAME)) +#define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \ + for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_start)(TARGET); \ + !CMC_(PFX, _iter_at_end)(&ITERNAME); \ + CMC_(PFX, _iter_next)(&ITERNAME)) -#endif /* CMC_FOREACH_H */ +#define CMC_FOREACH_REV(PFX, SNAME, ITERNAME, TARGET) \ + for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_end)(TARGET); \ + !CMC_(PFX, _iter_at_start)(&ITERNAME); \ + CMC_(PFX, _iter_prev)(&ITERNAME)) + +#endif /* CMC_UTL_FOREACH_H */ diff --git a/src/utl/futils.h b/src/utl/futils.h index e9516b1..60f5f6a 100644 --- a/src/utl/futils.h +++ b/src/utl/futils.h @@ -13,8 +13,8 @@ * another one every time. */ -#ifndef CMC_FUTILS_H -#define CMC_FUTILS_H +#ifndef CMC_UTL_FUTILS_H +#define CMC_UTL_FUTILS_H #include #include @@ -461,4 +461,4 @@ static inline size_t cmc_u64_hash_mix(uint64_t element) /* Can simply use cmp for basic data types */ -#endif /* CMC_FUTILS_H */ +#endif /* CMC_UTL_FUTILS_H */ diff --git a/src/utl/log.h b/src/utl/log.h index abcf609..7566190 100644 --- a/src/utl/log.h +++ b/src/utl/log.h @@ -56,8 +56,8 @@ * - If X is less than the level of FATAL, all logs are enabled */ -#ifndef CMC_LOG_H -#define CMC_LOG_H +#ifndef CMC_UTL_LOG_H +#define CMC_UTL_LOG_H #include #include @@ -178,4 +178,4 @@ skip: } } -#endif /* CMC_LOG_H */ +#endif /* CMC_UTL_LOG_H */ diff --git a/src/utl/mutex.h b/src/utl/mutex.h index ef5be43..81f9b76 100644 --- a/src/utl/mutex.h +++ b/src/utl/mutex.h @@ -22,8 +22,8 @@ * - cmc_mtx_trylock */ -#ifndef CMC_MUTEX_H -#define CMC_MUTEX_H +#ifndef CMC_UTL_MUTEX_H +#define CMC_UTL_MUTEX_H #include @@ -72,9 +72,9 @@ static inline bool cmc_mtx_init(struct cmc_mutex *mtx) mtx->mutex = CreateMutex(NULL, FALSE, NULL); if (mtx->mutex == NULL) - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; else - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; return mtx->mutex != NULL; @@ -82,9 +82,9 @@ static inline bool cmc_mtx_init(struct cmc_mutex *mtx) int err = pthread_mutex_init(&(mtx->mutex), NULL); if (err != 0) - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; else - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; return err == 0; #endif @@ -102,21 +102,21 @@ static inline bool cmc_mtx_destroy(struct cmc_mutex *mtx) #if defined(CMC_MUTEX_WINDOWS) if (!CloseHandle(mtx->mutex)) { - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; return false; } - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; return true; #elif defined(CMC_MUTEX_UNIX) if (pthread_mutex_destroy(&(mtx->mutex)) != 0) { - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; return false; } - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; return true; #endif } @@ -135,21 +135,21 @@ static inline bool cmc_mtx_lock(struct cmc_mutex *mtx) if (result == WAIT_FAILED || result == WAIT_ABANDONED) { - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; return false; } - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; return true; #elif defined(CMC_MUTEX_UNIX) if (pthread_mutex_lock(&mtx->mutex) != 0) { - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; return false; } - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; return true; #endif } @@ -165,19 +165,19 @@ static inline bool cmc_mtx_unlock(struct cmc_mutex *mtx) { #if defined(CMC_MUTEX_WINDOWS) if (!ReleaseMutex(mtx->mutex)) - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; else - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; - return mtx->flag == cmc_flags.OK; + return mtx->flag == CMC_FLAG_OK; #elif defined(CMC_MUTEX_UNIX) if (pthread_mutex_unlock(&mtx->mutex) != 0) - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; else - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; - return mtx->flag == cmc_flags.OK; + return mtx->flag == CMC_FLAG_OK; #endif } @@ -195,23 +195,23 @@ static inline bool cmc_mtx_trylock(struct cmc_mutex *mtx) if (result == WAIT_FAILED || result == WAIT_ABANDONED) { - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; return false; } - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; return result != WAIT_TIMEOUT; #elif defined(CMC_MUTEX_UNIX) int err = pthread_mutex_trylock(&mtx->mutex); if (err == EINVAL || err == EFAULT) - mtx->flag = cmc_flags.MUTEX; + mtx->flag = CMC_FLAG_MUTEX; else - mtx->flag = cmc_flags.OK; + mtx->flag = CMC_FLAG_OK; return err == 0; #endif } -#endif /* CMC_MUTEX_H */ +#endif /* CMC_UTL_MUTEX_H */ diff --git a/src/utl/test.h b/src/utl/test.h index d0badb9..a127607 100644 --- a/src/utl/test.h +++ b/src/utl/test.h @@ -34,8 +34,8 @@ * Define this macro to allow colored output. */ -#ifndef CMC_TEST_H -#define CMC_TEST_H +#ifndef CMC_UTL_TEST_H +#define CMC_UTL_TEST_H #include #include @@ -240,4 +240,4 @@ static void cmc_test_log(const char *unit_name, const char *current_test, \ } while (0) -#endif /* CMC_TEST_H */ +#endif /* CMC_UTL_TEST_H */ diff --git a/src/utl/thread.h b/src/utl/thread.h index bf309fb..c46950b 100644 --- a/src/utl/thread.h +++ b/src/utl/thread.h @@ -20,8 +20,8 @@ * - cmc_thrd_join */ -#ifndef CMC_THREAD_H -#define CMC_THREAD_H +#ifndef CMC_UTL_THREAD_H +#define CMC_UTL_THREAD_H #include #include @@ -97,21 +97,21 @@ static inline bool cmc_thrd_create(struct cmc_thread *thr, cmc_thread_proc proc, thr->thread = CreateThread(NULL, 0, cmc_thread_wrapper, thr, 0, NULL); if (!thr->thread) - thr->flag = cmc_flags.THREAD; + thr->flag = CMC_FLAG_THREAD; else - thr->flag = cmc_flags.OK; + thr->flag = CMC_FLAG_OK; - return thr->flag == cmc_flags.OK; + return thr->flag == CMC_FLAG_OK; #elif defined(CMC_THREAD_UNIX) thr->args = args; thr->process = proc; if (pthread_create(&(thr->thread), NULL, cmc_thread_wrapper, thr) != 0) - thr->flag = cmc_flags.THREAD; + thr->flag = CMC_FLAG_THREAD; else - thr->flag = cmc_flags.OK; + thr->flag = CMC_FLAG_OK; - return thr->flag == cmc_flags.OK; + return thr->flag == CMC_FLAG_OK; #endif } @@ -127,7 +127,7 @@ static inline bool cmc_thrd_join(struct cmc_thread *thr, int *result) #if defined(CMC_THREAD_WINDOWS) if (WaitForSingleObject(thr->thread, INFINITE) == WAIT_FAILED) { - thr->flag = cmc_flags.THREAD; + thr->flag = CMC_FLAG_THREAD; return false; } @@ -137,22 +137,22 @@ static inline bool cmc_thrd_join(struct cmc_thread *thr, int *result) { if (GetExitCodeThread(thr->thread, &exit_code) == 0) { - thr->flag = cmc_flags.THREAD; + thr->flag = CMC_FLAG_THREAD; return false; } else *result = (int)exit_code; } - thr->flag = cmc_flags.OK; + thr->flag = CMC_FLAG_OK; if (CloseHandle(thr->thread) == 0) { - thr->flag = cmc_flags.THREAD; + thr->flag = CMC_FLAG_THREAD; return false; } - thr->flag = cmc_flags.OK; + thr->flag = CMC_FLAG_OK; return true; #elif defined(CMC_THREAD_UNIX) @@ -160,7 +160,7 @@ static inline bool cmc_thrd_join(struct cmc_thread *thr, int *result) if (pthread_join(thr->thread, &exit_value) != 0) { - thr->flag = cmc_flags.THREAD; + thr->flag = CMC_FLAG_THREAD; return false; } @@ -169,10 +169,10 @@ static inline bool cmc_thrd_join(struct cmc_thread *thr, int *result) *result = (int)(intptr_t)exit_value; } - thr->flag = cmc_flags.OK; + thr->flag = CMC_FLAG_OK; return true; #endif } -#endif /* CMC_THREAD_H */ +#endif /* CMC_UTL_THREAD_H */ diff --git a/src/utl/timer.h b/src/utl/timer.h index 45b9990..cfa4357 100644 --- a/src/utl/timer.h +++ b/src/utl/timer.h @@ -12,8 +12,8 @@ * Simple timer macros utility for timing code execution. */ -#ifndef CMC_TIMER_H -#define CMC_TIMER_H +#ifndef CMC_UTL_TIMER_H +#define CMC_UTL_TIMER_H #include @@ -40,4 +40,4 @@ struct cmc_timer (double)(t__->stop - t__->start) * 1000.0 / CLOCKS_PER_SEC; \ } while (0) -#endif /* CMC_TIMER_H */ +#endif /* CMC_UTL_TIMER_H */ diff --git a/tests/contains.c b/tests/contains.c deleted file mode 100644 index 730bfba..0000000 --- a/tests/contains.c +++ /dev/null @@ -1,260 +0,0 @@ -#include "../src/macro_collections.h" -#include -#include -#include - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int) -CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int) -CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int) -CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int) -CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int) -CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int) -CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int) -CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int) -CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int) - -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, , int) -CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int) -CMC_COLLECTION_GENERATE(MULTISET, ms, mset, , int) - -int main(void) -{ - struct list *l = l_new(1000); - struct stack *s = s_new(1000); - struct queue *q = q_new(1000); - struct deque *d = d_new(1000); - struct linked *ll = ll_new(); - struct heap *h = h_new(1000, cmc_max_heap, intcmp); - struct tset *ts = ts_new(intcmp); - struct tmap *tm = tm_new(intcmp); - struct hset *hs = hs_new(1000, 0.6, intcmp, inthash); - struct hmap *hm = hm_new(1000, 0.6, intcmp, inthash); - struct iheap *ih = ih_new(1000, intcmp); - struct mmap *mm = mm_new(1000, 0.8, intcmp, inthash); - struct mset *ms = ms_new(1000, 0.6, intcmp, inthash); - - bool a[13] = { false, false, false, false, false, false, false, - false, false, false, false, false, false }, - b[13] = { false, false, false, false, false, false, false, - false, false, false, false, false, false }, - c[13] = { true, true, true, true, true, true, true, - true, true, true, true, true, true }; - - b[0] = d_contains(d, 1, intcmp); - b[1] = hm_contains(hm, 1); - b[2] = hs_contains(hs, 1); - b[3] = h_contains(h, 1); - b[4] = ll_contains(ll, 1, intcmp); - b[5] = l_contains(l, 1, intcmp); - b[6] = q_contains(q, 1, intcmp); - b[7] = s_contains(s, 1, intcmp); - b[8] = tm_contains(tm, 1); - b[9] = ts_contains(ts, 1); - - b[10] = ih_contains(ih, 1); - b[11] = mm_contains(mm, 1); - b[12] = ms_contains(ms, 1); - - for (int i = 1; i < 1001; i++) - { - if (i % 2 == 0) - { - d_push_front(d, i); - l_push_front(l, i); - ll_push_front(ll, i); - } - else - { - d_push_back(d, i); - l_push_back(l, i); - ll_push_back(ll, i); - } - - s_push(s, i); - q_enqueue(q, i); - h_insert(h, i); - ts_insert(ts, i); - tm_insert(tm, i, i); - hs_insert(hs, i); - hm_insert(hm, i, i); - - ih_insert(ih, i); - mm_insert(mm, i, i); - ms_insert(ms, i); - } - - for (int i = 1; i < 1001; i++) - { - c[0] = c[0] && d_contains(d, i, intcmp); - c[1] = c[1] && hm_contains(hm, i); - c[2] = c[2] && hs_contains(hs, i); - c[3] = c[3] && h_contains(h, i); - c[4] = c[4] && ll_contains(ll, i, intcmp); - c[5] = c[5] && l_contains(l, i, intcmp); - c[6] = c[6] && q_contains(q, i, intcmp); - c[7] = c[7] && s_contains(s, i, intcmp); - c[8] = c[8] && tm_contains(tm, i); - c[9] = c[9] && ts_contains(ts, i); - - c[10] = c[10] && ih_contains(ih, i); - c[11] = c[11] && mm_contains(mm, i); - c[12] = c[12] && ms_contains(ms, i); - } - - for (int i = -500; i < 1; i++) - { - a[0] = a[0] || d_contains(d, i, intcmp); - a[1] = a[1] || hm_contains(hm, i); - a[2] = a[2] || hs_contains(hs, i); - a[3] = a[3] || h_contains(h, i); - a[4] = a[4] || ll_contains(ll, i, intcmp); - a[5] = a[5] || l_contains(l, i, intcmp); - a[6] = a[6] || q_contains(q, i, intcmp); - a[7] = a[7] || s_contains(s, i, intcmp); - a[8] = a[8] || tm_contains(tm, i); - a[9] = a[9] || ts_contains(ts, i); - - a[10] = a[10] || ih_contains(ih, i); - a[11] = a[11] || mm_contains(mm, i); - a[12] = a[12] || ms_contains(ms, i); - } - - for (int i = 1001; i < 1500; i++) - { - a[0] = a[0] || d_contains(d, i, intcmp); - a[1] = a[1] || hm_contains(hm, i); - a[2] = a[2] || hs_contains(hs, i); - a[3] = a[3] || h_contains(h, i); - a[4] = a[4] || ll_contains(ll, i, intcmp); - a[5] = a[5] || l_contains(l, i, intcmp); - a[6] = a[6] || q_contains(q, i, intcmp); - a[7] = a[7] || s_contains(s, i, intcmp); - a[8] = a[8] || tm_contains(tm, i); - a[9] = a[9] || ts_contains(ts, i); - - a[10] = a[10] || ih_contains(ih, i); - a[11] = a[11] || mm_contains(mm, i); - a[12] = a[12] || ms_contains(ms, i); - } - - d_clear(d, NULL); - hm_clear(hm, NULL); - hs_clear(hs, NULL); - h_clear(h, NULL); - ll_clear(ll, NULL); - l_clear(l, NULL); - q_clear(q, NULL); - s_clear(s, NULL); - tm_clear(tm, NULL); - ts_clear(ts, NULL); - - ih_clear(ih, NULL); - mm_clear(mm, NULL); - ms_clear(ms, NULL); - - b[0] = b[0] || d_contains(d, 1, intcmp); - b[1] = b[1] || hm_contains(hm, 1); - b[2] = b[2] || hs_contains(hs, 1); - b[3] = b[3] || h_contains(h, 1); - b[4] = b[4] || ll_contains(ll, 1, intcmp); - b[5] = b[5] || l_contains(l, 1, intcmp); - b[6] = b[6] || q_contains(q, 1, intcmp); - b[7] = b[7] || s_contains(s, 1, intcmp); - b[8] = b[8] || tm_contains(tm, 1); - b[9] = b[9] || ts_contains(ts, 1); - - b[10] = b[10] || ih_contains(ih, 1); - b[11] = b[11] || mm_contains(mm, 1); - b[12] = b[12] || ms_contains(ms, 1); - - printf("-------------------- CONTAINS --------------------\n"); - if (c[0] && !a[0] && !b[0]) - printf("%12s PASSED\n", "DEQUE"); - else - printf("%12s FAILED\n", "DEQUE"); - if (c[1] && !a[1] && !b[1]) - printf("%12s PASSED\n", "HASHMAP"); - else - printf("%12s FAILED\n", "HASHMAP"); - if (c[2] && !a[2] && !b[2]) - printf("%12s PASSED\n", "HASHSET"); - else - printf("%12s FAILED\n", "HASHSET"); - if (c[3] && !a[3] && !b[3]) - printf("%12s PASSED\n", "HEAP"); - else - printf("%12s FAILED\n", "HEAP"); - if (c[4] && !a[4] && !b[4]) - printf("%12s PASSED\n", "LINKEDLIST"); - else - printf("%12s FAILED\n", "LINKEDLIST"); - if (c[5] && !a[5] && !b[5]) - printf("%12s PASSED\n", "LIST"); - else - printf("%12s FAILED\n", "LIST"); - if (c[6] && !a[6] && !b[6]) - printf("%12s PASSED\n", "QUEUE"); - else - printf("%12s FAILED\n", "QUEUE"); - if (c[7] && !a[7] && !b[7]) - printf("%12s PASSED\n", "STACK"); - else - printf("%12s FAILED\n", "STACK"); - if (c[8] && !a[8] && !b[8]) - printf("%12s PASSED\n", "TREEMAP"); - else - printf("%12s FAILED\n", "TREEMAP"); - if (c[9] && !a[9] && !b[9]) - printf("%12s PASSED\n", "TREESET"); - else - printf("%12s FAILED\n", "TREESET"); - if (c[10] && !a[10] && !b[10]) - printf("%12s PASSED\n", "INTERVALHEAP"); - else - printf("%12s FAILED\n", "INTERVALHEAP"); - if (c[11] && !a[11] && !b[11]) - printf("%12s PASSED\n", "MULTIMAP"); - else - printf("%12s FAILED\n", "MULTIMAP"); - if (c[12] && !a[12] && !b[12]) - printf("%12s PASSED\n", "MULTISET"); - else - printf("%12s FAILED\n", "MULTISET"); - - printf("\n\n"); - - l_free(l, NULL); - ll_free(ll, NULL); - s_free(s, NULL); - q_free(q, NULL); - d_free(d, NULL); - h_free(h, NULL); - ts_free(ts, NULL); - tm_free(tm, NULL); - hs_free(hs, NULL); - hm_free(hm, NULL); - - ih_free(ih, NULL); - mm_free(mm, NULL); - ms_free(ms, NULL); - - return 0; -} diff --git a/tests/foreach.c b/tests/foreach.c deleted file mode 100644 index 120d249..0000000 --- a/tests/foreach.c +++ /dev/null @@ -1,286 +0,0 @@ -#include "../src/macro_collections.h" -#include -#include -#include - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int) -CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int) -CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int) -CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int) -CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int) -CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int) -CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int) -CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int) -CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int) - -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, , int) -CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int) -CMC_COLLECTION_GENERATE(MULTISET, ms, mset, , int) - -int main(void) -{ - struct list *l = l_new(1000); - struct stack *s = s_new(1000); - struct queue *q = q_new(1000); - struct deque *d = d_new(1000); - struct linked *ll = ll_new(); - struct heap *h = h_new(1000, cmc_max_heap, intcmp); - struct tset *ts = ts_new(intcmp); - struct tmap *tm = tm_new(intcmp); - struct hset *hs = hs_new(1000, 0.6, intcmp, inthash); - struct hmap *hm = hm_new(1000, 0.6, intcmp, inthash); - struct iheap *ih = ih_new(1000, intcmp); - struct mmap *mm = mm_new(1000, 0.8, intcmp, inthash); - struct mset *ms = ms_new(1000, 0.6, intcmp, inthash); - - bool p = true; - - for (int i = 1; i < 10001; i++) - { - if (i % 2 == 0) - { - assert(d_push_front(d, i)); - assert(l_push_front(l, i)); - assert(ll_push_front(ll, i)); - } - else - { - assert(d_push_back(d, i)); - assert(l_push_back(l, i)); - assert(ll_push_back(ll, i)); - } - - assert(s_push(s, i)); - assert(q_enqueue(q, i)); - assert(h_insert(h, i)); - assert(ts_insert(ts, i)); - assert(tm_insert(tm, i, i)); - assert(hs_insert(hs, i)); - assert(hm_insert(hm, i, i)); - - assert(ih_insert(ih, i)); - assert(mm_insert(mm, i, i)); - assert(ms_insert(ms, i)); - } - - int sums[16] = { 0 }; - - CMC_FOR_EACH(d, deque, d, { sums[0] += d_iter_value(&iter); }); - - CMC_FOR_EACH(hm, hmap, hm, { - sums[1] += hm_iter_key(&iter); - sums[2] += hm_iter_value(&iter); - }); - - CMC_FOR_EACH(hs, hset, hs, { sums[3] += hs_iter_value(&iter); }); - - CMC_FOR_EACH(h, heap, h, { sums[4] += h_iter_value(&iter); }); - - CMC_FOR_EACH(ll, linked, ll, { sums[5] += ll_iter_value(&iter); }); - - CMC_FOR_EACH(l, list, l, { sums[6] += l_iter_value(&iter); }); - - CMC_FOR_EACH(q, queue, q, { sums[7] += q_iter_value(&iter); }); - - CMC_FOR_EACH(s, stack, s, { sums[8] += s_iter_value(&iter); }); - - CMC_FOR_EACH(tm, tmap, tm, { - sums[9] += tm_iter_key(&iter); - sums[10] += tm_iter_value(&iter); - }); - - CMC_FOR_EACH(ts, tset, ts, { sums[11] += ts_iter_value(&iter); }); - - CMC_FOR_EACH(ih, iheap, ih, { sums[12] += ih_iter_value(&iter); }); - - CMC_FOR_EACH(mm, mmap, mm, { - sums[13] += mm_iter_key(&iter); - sums[14] += mm_iter_value(&iter); - }); - - CMC_FOR_EACH(ms, mset, ms, { sums[15] += ms_iter_value(&iter); }); - - printf("\n-------------------- CMC_FOR_EACH --------------------\n"); - if (sums[0] == 50005000) - printf("%12s PASSED\n", "DEQUE"); - else - printf("%12s FAILED\n", "DEQUE"); - if (sums[1] == 50005000 && sums[2] == 50005000) - printf("%12s PASSED\n", "HASHMAP"); - else - printf("%12s FAILED\n", "HASHMAP"); - if (sums[3] == 50005000) - printf("%12s PASSED\n", "HASHSET"); - else - printf("%12s FAILED\n", "HASHSET"); - if (sums[4] == 50005000) - printf("%12s PASSED\n", "HEAP"); - else - printf("%12s FAILED\n", "HEAP"); - if (sums[5] == 50005000) - printf("%12s PASSED\n", "LINKEDLIST"); - else - printf("%12s FAILED\n", "LINKEDLIST"); - if (sums[6] == 50005000) - printf("%12s PASSED\n", "LIST"); - else - printf("%12s FAILED\n", "LIST"); - if (sums[7] == 50005000) - printf("%12s PASSED\n", "QUEUE"); - else - printf("%12s FAILED\n", "QUEUE"); - if (sums[8] == 50005000) - printf("%12s PASSED\n", "STACK"); - else - printf("%12s FAILED\n", "STACK"); - if (sums[9] == 50005000 && sums[10] == 50005000) - printf("%12s PASSED\n", "TREEMAP"); - else - printf("%12s FAILED\n", "TREEMAP"); - if (sums[11] == 50005000) - printf("%12s PASSED\n", "TREESET"); - else - printf("%12s FAILED\n", "TREESET"); - if (sums[12] == 50005000) - printf("%12s PASSED\n", "INTERVALHEAP"); - else - printf("%12s FAILED\n", "INTERVALHEAP"); - if (sums[13] == 50005000 && sums[14] == 50005000) - printf("%12s PASSED\n", "MULTIMAP"); - else - printf("%12s FAILED\n", "MULTIMAP"); - if (sums[15] == 50005000) - printf("%12s PASSED\n", "MULTISET"); - else - printf("%12s FAILED\n", "MULTISET"); - - printf("\n\n"); - - memset(sums, 0, sizeof sums); - - CMC_FOR_EACH_REV(d, deque, d, { sums[0] += d_iter_value(&iter); }); - - CMC_FOR_EACH_REV(hm, hmap, hm, { - sums[1] += hm_iter_key(&iter); - sums[2] += hm_iter_value(&iter); - }); - - CMC_FOR_EACH_REV(hs, hset, hs, { sums[3] += hs_iter_value(&iter); }); - - CMC_FOR_EACH_REV(h, heap, h, { sums[4] += h_iter_value(&iter); }); - - CMC_FOR_EACH_REV(ll, linked, ll, { sums[5] += ll_iter_value(&iter); }); - - CMC_FOR_EACH_REV(l, list, l, { sums[6] += l_iter_value(&iter); }); - - CMC_FOR_EACH_REV(q, queue, q, { sums[7] += q_iter_value(&iter); }); - - CMC_FOR_EACH_REV(s, stack, s, { sums[8] += s_iter_value(&iter); }); - - CMC_FOR_EACH_REV(tm, tmap, tm, { - sums[9] += tm_iter_key(&iter); - sums[10] += tm_iter_value(&iter); - }); - - CMC_FOR_EACH_REV(ts, tset, ts, { sums[11] += ts_iter_value(&iter); }); - - CMC_FOR_EACH_REV(ih, iheap, ih, { sums[12] += ih_iter_value(&iter); }); - - CMC_FOR_EACH_REV(mm, mmap, mm, { - sums[13] += mm_iter_key(&iter); - sums[14] += mm_iter_value(&iter); - }); - - CMC_FOR_EACH_REV(ms, mset, ms, { sums[15] += ms_iter_value(&iter); }); - - printf("-------------------- CMC_FOR_EACH_REV --------------------\n"); - if (sums[0] == 50005000) - printf("%12s PASSED\n", "DEQUE"); - else - printf("%12s FAILED\n", "DEQUE"); - if (sums[1] == 50005000 && sums[2] == 50005000) - printf("%12s PASSED\n", "HASHMAP"); - else - printf("%12s FAILED\n", "HASHMAP"); - if (sums[3] == 50005000) - printf("%12s PASSED\n", "HASHSET"); - else - printf("%12s FAILED\n", "HASHSET"); - if (sums[4] == 50005000) - printf("%12s PASSED\n", "HEAP"); - else - printf("%12s FAILED\n", "HEAP"); - if (sums[5] == 50005000) - printf("%12s PASSED\n", "LINKEDLIST"); - else - printf("%12s FAILED\n", "LINKEDLIST"); - if (sums[6] == 50005000) - printf("%12s PASSED\n", "LIST"); - else - printf("%12s FAILED\n", "LIST"); - if (sums[7] == 50005000) - printf("%12s PASSED\n", "QUEUE"); - else - printf("%12s FAILED\n", "QUEUE"); - if (sums[8] == 50005000) - printf("%12s PASSED\n", "STACK"); - else - printf("%12s FAILED\n", "STACK"); - if (sums[9] == 50005000 && sums[10] == 50005000) - printf("%12s PASSED\n", "TREEMAP"); - else - printf("%12s FAILED\n", "TREEMAP"); - if (sums[11] == 50005000) - printf("%12s PASSED\n", "TREESET"); - else - printf("%12s FAILED\n", "TREESET"); - if (sums[12] == 50005000) - printf("%12s PASSED\n", "INTERVALHEAP"); - else - printf("%12s FAILED\n", "INTERVALHEAP"); - if (sums[13] == 50005000 && sums[14] == 50005000) - printf("%12s PASSED\n", "MULTIMAP"); - else - printf("%12s FAILED\n", "MULTIMAP"); - if (sums[15] == 50005000) - printf("%12s PASSED\n", "MULTISET"); - else - printf("%12s FAILED\n", "MULTISET"); - - printf("\n\n"); - - l_free(l, NULL); - ll_free(ll, NULL); - s_free(s, NULL); - q_free(q, NULL); - d_free(d, NULL); - h_free(h, NULL); - ts_free(ts, NULL); - tm_free(tm, NULL); - hs_free(hs, NULL); - hm_free(hm, NULL); - - ih_free(ih, NULL); - mm_free(mm, NULL); - ms_free(ms, NULL); - - return 0; -} diff --git a/tests/iterators.c b/tests/iterators.c deleted file mode 100644 index dc51442..0000000 --- a/tests/iterators.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "../src/macro_collections.h" -#include - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int) -CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int) -CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int) -CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int) -CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int) -CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int) -CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, double) -CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int) -CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, double) - -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* K */, int) -CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, double) -CMC_COLLECTION_GENERATE(MULTISET, ms, mset, /* K */, int) - -#define ITERATOR_TEST(NAME, PFX, sname, initfunc, insertbody, sumbody, \ - validation1, validation2) \ - void NAME##_iterator_test(void) \ - { \ - int sum1 = 0; \ - double sum2 = 0.0; \ - \ - struct sname *coll = initfunc; \ - for (int i = 0; i < 10; i++) \ - { \ - insertbody; \ - } \ - \ - struct sname##_iter iter; \ - PFX##_iter_init(&iter, coll); \ - \ - for (int j = 0; j < 4; j++) \ - { \ - while (!PFX##_iter_end(&iter)) \ - { \ - sumbody; \ - PFX##_iter_next(&iter); \ - } \ - while (!PFX##_iter_start(&iter)) \ - { \ - sumbody; \ - PFX##_iter_prev(&iter); \ - } \ - } \ - \ - for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); \ - PFX##_iter_next(&iter)) \ - { \ - sumbody; \ - } \ - \ - for (PFX##_iter_to_end(&iter); !PFX##_iter_start(&iter); \ - PFX##_iter_prev(&iter)) \ - { \ - sumbody; \ - } \ - \ - PFX##_free(coll, NULL); \ - \ - if ((validation1) && (validation2)) \ - printf("%12s PASSED\n", #NAME); \ - else \ - printf("%12s FAILED\n", #NAME); \ - } - -ITERATOR_TEST(DEQUE, d, deque, d_new(20), d_push_front(coll, i), - sum1 += d_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(HASHMAP, hm, hmap, hm_new(50, 0.6, intcmp, inthash), - hm_insert(coll, i, (double)i / 10.0), sum1 += hm_iter_key(&iter); - sum2 += hm_iter_value(&iter), sum1 == 450, (int)sum2 == (int)45) -ITERATOR_TEST(HASHSET, hs, hset, hs_new(50, 0.6, intcmp, inthash), - hs_insert(coll, i), sum1 += hs_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(HEAP, h, heap, h_new(20, cmc_max_heap, intcmp), h_insert(coll, i), - sum1 += h_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(LINKEDLIST, ll, linked, ll_new(), ll_push_back(coll, i), - sum1 += ll_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(LIST, l, list, l_new(20), l_push_back(coll, i), - sum1 += l_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(QUEUE, q, queue, q_new(20), q_enqueue(coll, i), - sum1 += q_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(STACK, s, stack, s_new(20), s_push(coll, i), - sum1 += s_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(TREEMAP, tm, tmap, tm_new(intcmp), - tm_insert(coll, i, (double)i / 10.0), sum1 += tm_iter_key(&iter); - sum2 += tm_iter_value(&iter), sum1 == 450, (int)sum2 == (int)45) -ITERATOR_TEST(TREESET, ts, tset, ts_new(intcmp), ts_insert(coll, i), - sum1 += ts_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(INTERVALHEAP, ih, iheap, ih_new(20, intcmp), ih_insert(coll, i), - sum1 += ih_iter_value(&iter), sum1 == 450, 1) -ITERATOR_TEST(MULTIMAP, mm, mmap, mm_new(50, 0.8, intcmp, inthash), - mm_insert(coll, i, (double)i / 10.0), sum1 += mm_iter_key(&iter); - sum2 += mm_iter_value(&iter), sum1 == 450, (int)sum2 == (int)45) -ITERATOR_TEST(MULTISET, ms, mset, ms_new(50, 0.6, intcmp, inthash), - ms_insert(coll, i), sum1 += ms_iter_value(&iter); - sum2 += ms_iter_multiplicity(&iter), sum1 == 450, - (size_t)sum2 == 100) - -int main(void) -{ - printf("\n-------------------- ITERATORS --------------------\n"); - DEQUE_iterator_test(); - HASHMAP_iterator_test(); - HASHSET_iterator_test(); - HEAP_iterator_test(); - LINKEDLIST_iterator_test(); - LIST_iterator_test(); - QUEUE_iterator_test(); - STACK_iterator_test(); - TREEMAP_iterator_test(); - TREESET_iterator_test(); - - INTERVALHEAP_iterator_test(); - MULTIMAP_iterator_test(); - MULTISET_iterator_test(); - - printf("\n\n"); - - return 0; -} diff --git a/tests/main/src/bitset.c b/tests/main/src/bitset.c index fdd081c..5975085 100644 --- a/tests/main/src/bitset.c +++ b/tests/main/src/bitset.c @@ -75,7 +75,7 @@ struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, return ((void *)0); } _bitset_->capacity = capacity; - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; _bitset_->alloc = alloc; _bitset_->callbacks = callbacks; return _bitset_; @@ -97,7 +97,7 @@ struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, if (!_bitset_.buffer) return _bitset_; _bitset_.capacity = capacity; - _bitset_.flag = cmc_flags.OK; + _bitset_.flag = CMC_FLAG_OK; _bitset_.alloc = alloc; _bitset_.callbacks = callbacks; return _bitset_; @@ -119,7 +119,7 @@ void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, else _bitset_->alloc = alloc; _bitset_->callbacks = callbacks; - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; } _Bool bs_set(struct bitset *_bitset_, size_t bit_index) { @@ -128,7 +128,7 @@ _Bool bs_set(struct bitset *_bitset_, size_t bit_index) const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->create) _bitset_->callbacks->create(); return 1; @@ -137,7 +137,7 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) { if (to < from) { - _bitset_->flag = cmc_flags.INVALID; + _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) @@ -161,7 +161,7 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[i] |= ~((cmc_bitset_word)0); _bitset_->buffer[end_index] |= end_mask; } - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->create) _bitset_->callbacks->create(); return 1; @@ -173,7 +173,7 @@ _Bool bs_clear(struct bitset *_bitset_, size_t bit_index) const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->delete) _bitset_->callbacks->delete (); return 1; @@ -182,7 +182,7 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) { if (to < from) { - _bitset_->flag = cmc_flags.INVALID; + _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) @@ -206,7 +206,7 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[i] = 0; _bitset_->buffer[end_index] &= ~end_mask; } - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->delete) _bitset_->callbacks->delete (); return 1; @@ -218,7 +218,7 @@ _Bool bs_flip(struct bitset *_bitset_, size_t bit_index) const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->update) _bitset_->callbacks->update(); return 1; @@ -227,7 +227,7 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) { if (to < from) { - _bitset_->flag = cmc_flags.INVALID; + _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) @@ -251,7 +251,7 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[i] ^= ones; _bitset_->buffer[end_index] ^= end_mask; } - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->update) _bitset_->callbacks->update(); return 1; @@ -274,7 +274,7 @@ _Bool bs_set_all(struct bitset *_bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = ~((cmc_bitset_word)0); - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->create) _bitset_->callbacks->create(); return 1; @@ -283,7 +283,7 @@ _Bool bs_clear_all(struct bitset *_bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = 0; - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->delete) _bitset_->callbacks->delete (); return 1; @@ -292,7 +292,7 @@ _Bool bs_flip_all(struct bitset *_bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; if (_bitset_->callbacks && _bitset_->callbacks->create) _bitset_->callbacks->create(); return 1; @@ -311,7 +311,7 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) { if (n_bits == 0) { - _bitset_->flag = cmc_flags.INVALID; + _bitset_->flag = CMC_FLAG_INVALID; return 0; } size_t words = bs_bit_to_index(n_bits - 1) + 1; @@ -321,7 +321,7 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); if (!new_buffer) { - _bitset_->flag = cmc_flags.ALLOC; + _bitset_->flag = CMC_FLAG_ALLOC; return 0; } _bitset_->buffer = new_buffer; @@ -331,7 +331,7 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) _bitset_->capacity = words; if (_bitset_->callbacks && _bitset_->callbacks->resize) _bitset_->callbacks->resize(); - _bitset_->flag = cmc_flags.OK; + _bitset_->flag = CMC_FLAG_OK; return 1; } diff --git a/tests/main/src/deque.c b/tests/main/src/deque.c index ba1e982..00c5992 100644 --- a/tests/main/src/deque.c +++ b/tests/main/src/deque.c @@ -36,10 +36,6 @@ struct deque *d_new(size_t capacity, struct deque_fval *f_val); struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -struct deque d_init(size_t capacity, struct deque_fval *f_val); -struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); void d_clear(struct deque *_deque_); void d_free(struct deque *_deque_); void d_release(struct deque _deque_); @@ -103,40 +99,12 @@ struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, _deque_->count = 0; _deque_->front = 0; _deque_->back = 0; - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; _deque_->f_val = f_val; _deque_->alloc = alloc; _deque_->callbacks = callbacks; return _deque_; } -struct deque d_init(size_t capacity, struct deque_fval *f_val) -{ - return d_init_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - struct deque _deque_ = { 0 }; - if (capacity < 1) - return _deque_; - if (!f_val) - return _deque_; - if (!alloc) - alloc = &cmc_alloc_node_default; - _deque_.buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_deque_.buffer) - return _deque_; - _deque_.capacity = capacity; - _deque_.count = 0; - _deque_.front = 0; - _deque_.back = 0; - _deque_.flag = cmc_flags.OK; - _deque_.f_val = f_val; - _deque_.alloc = alloc; - _deque_.callbacks = callbacks; - return _deque_; -} void d_clear(struct deque *_deque_) { if (_deque_->f_val->free) @@ -151,7 +119,7 @@ void d_clear(struct deque *_deque_) _deque_->count = 0; _deque_->front = 0; _deque_->back = 0; - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; } void d_free(struct deque *_deque_) { @@ -186,7 +154,7 @@ void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, else _deque_->alloc = alloc; _deque_->callbacks = callbacks; - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; } _Bool d_push_front(struct deque *_deque_, size_t value) { @@ -199,7 +167,7 @@ _Bool d_push_front(struct deque *_deque_, size_t value) (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; _deque_->buffer[_deque_->front] = value; _deque_->count++; - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->create) _deque_->callbacks->create(); return 1; @@ -215,7 +183,7 @@ _Bool d_push_back(struct deque *_deque_, size_t value) _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; _deque_->count++; - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->create) _deque_->callbacks->create(); return 1; @@ -224,14 +192,14 @@ _Bool d_pop_front(struct deque *_deque_) { if (d_empty(_deque_)) { - _deque_->flag = cmc_flags.EMPTY; + _deque_->flag = CMC_FLAG_EMPTY; return 0; } _deque_->buffer[_deque_->front] = (size_t){ 0 }; _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; _deque_->count--; - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->delete) _deque_->callbacks->delete (); return 1; @@ -240,14 +208,14 @@ _Bool d_pop_back(struct deque *_deque_) { if (d_empty(_deque_)) { - _deque_->flag = cmc_flags.EMPTY; + _deque_->flag = CMC_FLAG_EMPTY; return 0; } _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; _deque_->buffer[_deque_->back] = (size_t){ 0 }; _deque_->count--; - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->delete) _deque_->callbacks->delete (); return 1; @@ -256,10 +224,10 @@ size_t d_front(struct deque *_deque_) { if (d_empty(_deque_)) { - _deque_->flag = cmc_flags.EMPTY; + _deque_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->read) _deque_->callbacks->read(); return _deque_->buffer[_deque_->front]; @@ -268,10 +236,10 @@ size_t d_back(struct deque *_deque_) { if (d_empty(_deque_)) { - _deque_->flag = cmc_flags.EMPTY; + _deque_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->read) _deque_->callbacks->read(); return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 @@ -279,7 +247,7 @@ size_t d_back(struct deque *_deque_) } _Bool d_contains(struct deque *_deque_, size_t value) { - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { @@ -316,18 +284,18 @@ int d_flag(struct deque *_deque_) } _Bool d_resize(struct deque *_deque_, size_t capacity) { - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; if (_deque_->capacity == capacity) goto success; if (capacity < _deque_->count) { - _deque_->flag = cmc_flags.INVALID; + _deque_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _deque_->alloc->malloc(sizeof(size_t) * capacity); if (!new_buffer) { - _deque_->flag = cmc_flags.ALLOC; + _deque_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) @@ -351,7 +319,7 @@ struct deque *d_copy_of(struct deque *_deque_) _deque_->alloc, _deque_->callbacks); if (!result) { - _deque_->flag = cmc_flags.ERROR; + _deque_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (_deque_->f_val->cpy) @@ -373,13 +341,13 @@ struct deque *d_copy_of(struct deque *_deque_) result->count = _deque_->count; result->front = 0; result->back = _deque_->count; - _deque_->flag = cmc_flags.OK; + _deque_->flag = CMC_FLAG_OK; return result; } _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_) { - _deque1_->flag = cmc_flags.OK; - _deque2_->flag = cmc_flags.OK; + _deque1_->flag = CMC_FLAG_OK; + _deque2_->flag = CMC_FLAG_OK; if (_deque1_->count != _deque2_->count) return 0; size_t i, j, k; @@ -397,10 +365,11 @@ struct cmc_string d_to_string(struct deque *_deque_) { struct cmc_string str; struct deque *d_ = _deque_; - int n = - snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, "deque", "size_t", - d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, - d_->flag, d_->f_val, d_->alloc, d_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_deque, + "CMC_PARAM_SNAME((d, deque, , , size_t))", + "CMC_PARAM_V((d, deque, , , size_t))", d_, d_->buffer, + d_->capacity, d_->count, d_->front, d_->back, d_->flag, + d_->f_val, d_->alloc, d_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool d_print(struct deque *_deque_, FILE *fptr) diff --git a/tests/main/src/hashbidimap.c b/tests/main/src/hashbidimap.c index d8e98b8..f9cb231 100644 --- a/tests/main/src/hashbidimap.c +++ b/tests/main/src/hashbidimap.c @@ -142,7 +142,7 @@ struct hashbidimap *hbm_new(size_t capacity, double load, _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; @@ -180,10 +180,10 @@ struct hashbidimap *hbm_new_custom(size_t capacity, double load, _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _map_->alloc = alloc; _map_->callbacks = callbacks; _map_->it_start = hbm_impl_it_start; @@ -207,7 +207,7 @@ void hbm_clear(struct hashbidimap *_map_) _map_->buffer[i][1] = ((void *)0); } _map_->count = 0; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; } void hbm_free(struct hashbidimap *_map_) { @@ -223,7 +223,7 @@ void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, else _map_->alloc = alloc; _map_->callbacks = callbacks; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; } _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) { @@ -235,7 +235,7 @@ _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) if (hbm_impl_get_entry_by_key(_map_, key) != ((void *)0) || hbm_impl_get_entry_by_val(_map_, value) != ((void *)0)) { - _map_->flag = cmc_flags.DUPLICATE; + _map_->flag = CMC_FLAG_DUPLICATE; return 0; } struct hashbidimap_entry *entry = hbm_impl_new_entry(_map_, key, value); @@ -250,11 +250,11 @@ _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) if (val_entry) *val_entry = ((void *)1); _map_->alloc->free(entry); - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } _map_->count++; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->create) _map_->callbacks->create(); return 1; @@ -263,27 +263,27 @@ _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) { if (hbm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry **key_entry, **val_entry; val_entry = hbm_impl_get_entry_by_val(_map_, val); if (!val_entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) goto success; if (hbm_impl_get_entry_by_key(_map_, new_key) != ((void *)0)) { - _map_->flag = cmc_flags.DUPLICATE; + _map_->flag = CMC_FLAG_DUPLICATE; return 0; } key_entry = (*val_entry)->ref[0]; if (!key_entry || *key_entry != *val_entry) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry *to_add = *key_entry; @@ -294,11 +294,11 @@ _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) { to_add->key = tmp_key; *key_entry = to_add; - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } success: - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->update) _map_->callbacks->update(); return 1; @@ -307,27 +307,27 @@ _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) { if (hbm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry **key_entry, **val_entry; key_entry = hbm_impl_get_entry_by_key(_map_, key); if (!key_entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) goto success; if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) { - _map_->flag = cmc_flags.DUPLICATE; + _map_->flag = CMC_FLAG_DUPLICATE; return 0; } val_entry = (*key_entry)->ref[1]; if (!val_entry || *val_entry != *key_entry) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry *to_add = *val_entry; @@ -338,11 +338,11 @@ _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) { to_add->value = tmp_val; *val_entry = to_add; - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } success: - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->update) _map_->callbacks->update(); return 1; @@ -352,20 +352,20 @@ _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, { if (hbm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry **key_entry, **val_entry; key_entry = hbm_impl_get_entry_by_key(_map_, key); if (!key_entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } val_entry = (*key_entry)->ref[1]; if (!val_entry || *val_entry != *key_entry) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } if (out_key) @@ -376,7 +376,7 @@ _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, *key_entry = ((void *)1); *val_entry = ((void *)1); _map_->count--; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->delete) _map_->callbacks->delete (); return 1; @@ -386,20 +386,20 @@ _Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, { if (hbm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry **key_entry, **val_entry; val_entry = hbm_impl_get_entry_by_val(_map_, val); if (!val_entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } key_entry = (*val_entry)->ref[0]; if (!key_entry || *key_entry != *val_entry) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } if (out_key) @@ -410,7 +410,7 @@ _Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, *key_entry = ((void *)1); *val_entry = ((void *)1); _map_->count--; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->delete) _map_->callbacks->delete (); return 1; @@ -420,10 +420,10 @@ size_t hbm_get_key(struct hashbidimap *_map_, size_t val) struct hashbidimap_entry **entry = hbm_impl_get_entry_by_val(_map_, val); if (!entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return (*entry)->key; @@ -433,17 +433,17 @@ size_t hbm_get_val(struct hashbidimap *_map_, size_t key) struct hashbidimap_entry **entry = hbm_impl_get_entry_by_key(_map_, key); if (!entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return (*entry)->value; } _Bool hbm_contains_key(struct hashbidimap *_map_, size_t key) { - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); @@ -451,7 +451,7 @@ _Bool hbm_contains_key(struct hashbidimap *_map_, size_t key) } _Bool hbm_contains_val(struct hashbidimap *_map_, size_t val) { - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); @@ -483,20 +483,20 @@ int hbm_flag(struct hashbidimap *_map_) } _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) { - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } size_t new_cap = hbm_impl_calculate_size(capacity); if (new_cap < _map_->count / _map_->load) { - _map_->flag = cmc_flags.INVALID; + _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashbidimap *_new_map_ = @@ -504,7 +504,7 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) _map_->alloc, ((void *)0)); if (!_new_map_) { - _map_->flag = cmc_flags.ALLOC; + _map_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _map_->capacity; i++) @@ -522,7 +522,7 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } _new_map_->count++; @@ -534,7 +534,7 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry *(*tmp_buff)[2] = _map_->buffer; @@ -554,7 +554,7 @@ struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) _map_->f_val, _map_->alloc, _map_->callbacks); if (!result) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } for (size_t i = 0; i < _map_->capacity; i++) @@ -579,13 +579,13 @@ struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) result->count++; } } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; return result; } _Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_) { - _map1_->flag = cmc_flags.OK; - _map2_->flag = cmc_flags.OK; + _map1_->flag = CMC_FLAG_OK; + _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashbidimap *_mapA_; @@ -619,10 +619,12 @@ struct cmc_string hbm_to_string(struct hashbidimap *_map_) { struct cmc_string str; struct hashbidimap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashbidimap, - "hashbidimap", "size_t", "size_t", m_, m_->buffer, - m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, - m_->f_val, m_->alloc, m_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashbidimap, + "CMC_PARAM_SNAME((hbm, hashbidimap, , size_t, size_t))", + "CMC_PARAM_K((hbm, hashbidimap, , size_t, size_t))", + "CMC_PARAM_V((hbm, hashbidimap, , size_t, size_t))", m_, + m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, m_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool hbm_print(struct hashbidimap *_map_, FILE *fptr) @@ -795,7 +797,7 @@ size_t hbm_iter_key(struct hashbidimap_iter *iter) { if (hbm_empty(iter->target)) { - iter->target->flag = cmc_flags.EMPTY; + iter->target->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } return iter->target->buffer[iter->cursor][0]->key; @@ -804,7 +806,7 @@ size_t hbm_iter_value(struct hashbidimap_iter *iter) { if (hbm_empty(iter->target)) { - iter->target->flag = cmc_flags.EMPTY; + iter->target->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } return iter->target->buffer[iter->cursor][0]->value; diff --git a/tests/main/src/hashmap.c b/tests/main/src/hashmap.c index b771ab4..11c6b46 100644 --- a/tests/main/src/hashmap.c +++ b/tests/main/src/hashmap.c @@ -57,13 +57,6 @@ struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, - struct hashmap_fval *f_val); -struct hashmap hm_init_custom(size_t capacity, double load, - struct hashmap_fkey *f_key, - struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); void hm_clear(struct hashmap *_map_); void hm_free(struct hashmap *_map_); void hm_release(struct hashmap _map_); @@ -140,48 +133,13 @@ struct hashmap *hm_new_custom(size_t capacity, double load, _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; _map_->callbacks = callbacks; return _map_; } -struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, - struct hashmap_fval *f_val) -{ - return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), - ((void *)0)); -} -struct hashmap hm_init_custom(size_t capacity, double load, - struct hashmap_fkey *f_key, - struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - struct hashmap _map_ = { 0 }; - if (capacity == 0 || load <= 0 || load >= 1) - return _map_; - if (capacity >= 0xffffffffffffffffULL * load) - return _map_; - if (!f_key || !f_val) - return _map_; - size_t real_capacity = hm_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); - if (!_map_.buffer) - return _map_; - _map_.count = 0; - _map_.capacity = real_capacity; - _map_.load = load; - _map_.flag = cmc_flags.OK; - _map_.f_key = f_key; - _map_.f_val = f_val; - _map_.alloc = alloc; - _map_.callbacks = callbacks; - return _map_; -} void hm_clear(struct hashmap *_map_) { if (_map_->f_key->free || _map_->f_val->free) @@ -200,7 +158,7 @@ void hm_clear(struct hashmap *_map_) } memset(_map_->buffer, 0, sizeof(struct hashmap_entry) * _map_->capacity); _map_->count = 0; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; } void hm_free(struct hashmap *_map_) { @@ -247,7 +205,7 @@ void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, else _map_->alloc = alloc; _map_->callbacks = callbacks; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; } _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) { @@ -258,7 +216,7 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) } if (hm_impl_get_entry(_map_, key) != ((void *)0)) { - _map_->flag = cmc_flags.DUPLICATE; + _map_->flag = CMC_FLAG_DUPLICATE; return 0; } size_t hash = _map_->f_key->hash(key); @@ -302,7 +260,7 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) } } _map_->count++; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->create) _map_->callbacks->create(); return 1; @@ -312,19 +270,19 @@ _Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, { if (hm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (old_value) *old_value = entry->value; entry->value = new_value; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->update) _map_->callbacks->update(); return 1; @@ -333,13 +291,13 @@ _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) { if (hm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_entry *result = hm_impl_get_entry(_map_, key); if (result == ((void *)0)) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_value) @@ -349,7 +307,7 @@ _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) result->dist = 0; result->state = CMC_ES_DELETED; _map_->count--; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->delete) _map_->callbacks->delete (); return 1; @@ -358,7 +316,7 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) { if (hm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_iter iter = hm_iter_start(_map_); @@ -387,7 +345,7 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) { if (hm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_iter iter = hm_iter_start(_map_); @@ -416,16 +374,16 @@ size_t hm_get(struct hashmap *_map_, size_t key) { if (hm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return entry->value; @@ -434,23 +392,23 @@ size_t *hm_get_ref(struct hashmap *_map_, size_t key) { if (hm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return &(entry->value); } _Bool hm_contains(struct hashmap *_map_, size_t key) { - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _Bool result = hm_impl_get_entry(_map_, key) != ((void *)0); if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); @@ -482,20 +440,20 @@ int hm_flag(struct hashmap *_map_) } _Bool hm_resize(struct hashmap *_map_, size_t capacity) { - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hm_impl_calculate_size(capacity); if (theoretical_size < _map_->count / _map_->load) { - _map_->flag = cmc_flags.INVALID; + _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashmap *_new_map_ = @@ -503,7 +461,7 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) _map_->alloc, ((void *)0)); if (!_new_map_) { - _map_->flag = cmc_flags.ALLOC; + _map_->flag = CMC_FLAG_ALLOC; return 0; } struct hashmap_iter iter = hm_iter_start(_map_); @@ -516,7 +474,7 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) if (_map_->count != _new_map_->count) { hm_free(_new_map_); - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashmap_entry *tmp_b = _map_->buffer; @@ -540,7 +498,7 @@ struct hashmap *hm_copy_of(struct hashmap *_map_) _map_->f_val, _map_->alloc, _map_->callbacks); if (!result) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (_map_->f_key->cpy || _map_->f_val->cpy) @@ -573,13 +531,13 @@ struct hashmap *hm_copy_of(struct hashmap *_map_) memcpy(result->buffer, _map_->buffer, sizeof(struct hashmap_entry) * _map_->capacity); result->count = _map_->count; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; return result; } _Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_) { - _map1_->flag = cmc_flags.OK; - _map2_->flag = cmc_flags.OK; + _map1_->flag = CMC_FLAG_OK; + _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashmap_iter iter = hm_iter_start(_map1_); @@ -598,10 +556,12 @@ struct cmc_string hm_to_string(struct hashmap *_map_) { struct cmc_string str; struct hashmap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmap, "hashmap", - "size_t", "size_t", m_, m_->buffer, m_->capacity, - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, - m_->alloc, m_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmap, + "CMC_PARAM_SNAME((hm, hashmap, , size_t, size_t))", + "CMC_PARAM_K((hm, hashmap, , size_t, size_t))", + "CMC_PARAM_V((hm, hashmap, , size_t, size_t))", m_, + m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, m_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool hm_print(struct hashmap *_map_, FILE *fptr) diff --git a/tests/main/src/hashmultimap.c b/tests/main/src/hashmultimap.c index ac1471e..ae280f9 100644 --- a/tests/main/src/hashmultimap.c +++ b/tests/main/src/hashmultimap.c @@ -134,7 +134,7 @@ struct hashmultimap *hmm_new(size_t capacity, double load, _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; @@ -169,7 +169,7 @@ struct hashmultimap *hmm_new_custom(size_t capacity, double load, _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; @@ -195,7 +195,7 @@ void hmm_clear(struct hashmultimap *_map_) memset(_map_->buffer, 0, sizeof(struct hashmultimap_entry *[2]) * _map_->capacity); _map_->count = 0; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; } void hmm_free(struct hashmultimap *_map_) { @@ -240,7 +240,7 @@ void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, else _map_->alloc = alloc; _map_->callbacks = callbacks; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; } _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) { @@ -264,7 +264,7 @@ _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) _map_->buffer[pos][1] = entry; } _map_->count++; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->create) _map_->callbacks->create(); return 1; @@ -274,19 +274,19 @@ _Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, { if (hmm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (old_value) *old_value = entry->value; entry->value = new_value; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->update) _map_->callbacks->update(); return 1; @@ -296,14 +296,14 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, { if (hmm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; if (entry == ((void *)0)) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (old_values) @@ -311,13 +311,13 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t total = hmm_impl_key_count(_map_, key); if (total == 0) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } *old_values = _map_->alloc->malloc(sizeof(size_t) * total); if (!(*old_values)) { - _map_->flag = cmc_flags.ALLOC; + _map_->flag = CMC_FLAG_ALLOC; return 0; } } @@ -333,7 +333,7 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, } entry = entry->next; } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->update) _map_->callbacks->update(); return index; @@ -342,7 +342,7 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) { if (hmm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } size_t hash = _map_->f_key->hash(key); @@ -352,7 +352,7 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) &(_map_->buffer[hash % _map_->capacity][1]); if (*head == ((void *)0)) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } struct hashmultimap_entry *entry = *head; @@ -367,7 +367,7 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) } else { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } } @@ -396,13 +396,13 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) } if (!found) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } } _map_->alloc->free(entry); _map_->count--; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->delete) _map_->callbacks->delete (); return 1; @@ -412,7 +412,7 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, { if (hmm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } size_t hash = _map_->f_key->hash(key); @@ -422,7 +422,7 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, &(_map_->buffer[hash % _map_->capacity][1]); if (*head == ((void *)0)) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_values) @@ -430,13 +430,13 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t total = hmm_impl_key_count(_map_, key); if (total == 0) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } *out_values = _map_->alloc->malloc(sizeof(size_t) * total); if (!(*out_values)) { - _map_->flag = cmc_flags.ALLOC; + _map_->flag = CMC_FLAG_ALLOC; return 0; } } @@ -477,7 +477,7 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, } } _map_->count -= index; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->delete) _map_->callbacks->delete (); return index; @@ -486,7 +486,7 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) { if (hmm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } size_t max_key; @@ -512,7 +512,7 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) *key = max_key; if (value) *value = max_val; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return 1; @@ -521,7 +521,7 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) { if (hmm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } size_t min_key; @@ -547,7 +547,7 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) *key = min_key; if (value) *value = min_val; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return 1; @@ -556,16 +556,16 @@ size_t hmm_get(struct hashmultimap *_map_, size_t key) { if (hmm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return entry->value; @@ -574,23 +574,23 @@ size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) { if (hmm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return &(entry->value); } _Bool hmm_contains(struct hashmultimap *_map_, size_t key) { - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0); if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); @@ -626,20 +626,20 @@ int hmm_flag(struct hashmultimap *_map_) } _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) { - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hmm_impl_calculate_size(capacity); if (theoretical_size < _map_->count / _map_->load) { - _map_->flag = cmc_flags.INVALID; + _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashmultimap *_new_map_ = @@ -647,7 +647,7 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) _map_->alloc, ((void *)0)); if (!_new_map_) { - _map_->flag = cmc_flags.ALLOC; + _map_->flag = CMC_FLAG_ALLOC; return 0; } struct hashmultimap_iter iter = hmm_iter_start(_map_); @@ -660,7 +660,7 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) if (_map_->count != _new_map_->count) { hmm_free(_new_map_); - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashmultimap_entry *(*tmp_b)[2] = _map_->buffer; @@ -684,7 +684,7 @@ struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } struct hashmultimap_iter iter = hmm_iter_start(_map_); @@ -702,13 +702,13 @@ struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) } } result->callbacks = _map_->callbacks; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; return result; } _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_) { - _map1_->flag = cmc_flags.OK; - _map2_->flag = cmc_flags.OK; + _map1_->flag = CMC_FLAG_OK; + _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashmultimap_iter iter = hmm_iter_start(_map1_); @@ -724,10 +724,12 @@ struct cmc_string hmm_to_string(struct hashmultimap *_map_) { struct cmc_string str; struct hashmultimap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmultimap, - "hashmultimap", "size_t", "size_t", m_, m_->buffer, - m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, - m_->f_val, m_->alloc, m_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmultimap, + "CMC_PARAM_SNAME((hmm, hashmultimap, , size_t, size_t))", + "CMC_PARAM_K((hmm, hashmultimap, , size_t, size_t))", + "CMC_PARAM_V((hmm, hashmultimap, , size_t, size_t))", m_, + m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, m_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool hmm_print(struct hashmultimap *_map_, FILE *fptr) diff --git a/tests/main/src/hashmultiset.c b/tests/main/src/hashmultiset.c index f51a4d0..1da5571 100644 --- a/tests/main/src/hashmultiset.c +++ b/tests/main/src/hashmultiset.c @@ -137,7 +137,7 @@ struct hashmultiset *hms_new(size_t capacity, double load, _set_->cardinality = 0; _set_->capacity = real_capacity; _set_->load = load; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; _set_->callbacks = ((void *)0); @@ -171,7 +171,7 @@ struct hashmultiset *hms_new_custom(size_t capacity, double load, _set_->cardinality = 0; _set_->capacity = real_capacity; _set_->load = load; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; _set_->callbacks = callbacks; @@ -193,7 +193,7 @@ void hms_clear(struct hashmultiset *_set_) memset(_set_->buffer, 0, sizeof(struct hashmultiset_entry) * _set_->capacity); _set_->count = 0; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; } void hms_free(struct hashmultiset *_set_) { @@ -219,7 +219,7 @@ void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, else _set_->alloc = alloc; _set_->callbacks = callbacks; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; } _Bool hms_insert(struct hashmultiset *_set_, size_t value) { @@ -228,13 +228,13 @@ _Bool hms_insert(struct hashmultiset *_set_, size_t value) hms_impl_insert_and_return(_set_, value, &new_node); if (!entry) { - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return 0; } if (!new_node) entry->multiplicity++; _set_->cardinality++; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->create) _set_->callbacks->create(); return 1; @@ -248,7 +248,7 @@ _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count) hms_impl_insert_and_return(_set_, value, &new_node); if (!entry) { - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return 0; } if (new_node) @@ -257,7 +257,7 @@ _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count) entry->multiplicity += count; _set_->cardinality += count; success: - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->create) _set_->callbacks->create(); return 1; @@ -288,7 +288,7 @@ _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) (_set_->cardinality - entry->multiplicity) + multiplicity; entry->multiplicity = multiplicity; success: - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->update) _set_->callbacks->update(); return 1; @@ -297,13 +297,13 @@ _Bool hms_remove(struct hashmultiset *_set_, size_t value) { if (hms_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); if (!result) { - _set_->flag = cmc_flags.NOT_FOUND; + _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (result->multiplicity > 1) @@ -317,7 +317,7 @@ _Bool hms_remove(struct hashmultiset *_set_, size_t value) _set_->count--; } _set_->cardinality--; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->delete) _set_->callbacks->delete (); return 1; @@ -326,13 +326,13 @@ size_t hms_remove_all(struct hashmultiset *_set_, size_t value) { if (hms_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); if (!result) { - _set_->flag = cmc_flags.NOT_FOUND; + _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } size_t removed = result->multiplicity; @@ -342,7 +342,7 @@ size_t hms_remove_all(struct hashmultiset *_set_, size_t value) result->state = CMC_ES_DELETED; _set_->count--; _set_->cardinality -= removed; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->delete) _set_->callbacks->delete (); return removed; @@ -351,7 +351,7 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value) { if (hms_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } size_t max_val; @@ -367,7 +367,7 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value) } if (value) *value = max_val; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); return 1; @@ -376,7 +376,7 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value) { if (hms_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } size_t min_val; @@ -392,7 +392,7 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value) } if (value) *value = min_val; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); return 1; @@ -400,7 +400,7 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value) size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value) { struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); if (!entry) @@ -409,7 +409,7 @@ size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value) } _Bool hms_contains(struct hashmultiset *_set_, size_t value) { - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; _Bool result = hms_impl_get_entry(_set_, value) != ((void *)0); if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); @@ -445,27 +445,27 @@ int hms_flag(struct hashmultiset *_set_) } _Bool hms_resize(struct hashmultiset *_set_, size_t capacity) { - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->capacity == capacity) goto success; if (_set_->capacity > capacity / _set_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _set_->load) { - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hms_impl_calculate_size(capacity); if (theoretical_size < _set_->count / _set_->load) { - _set_->flag = cmc_flags.INVALID; + _set_->flag = CMC_FLAG_INVALID; return 0; } struct hashmultiset *_new_set_ = hms_new_custom( capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!_new_set_) { - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return 0; } struct hashmultiset_iter iter = hms_iter_start(_set_); @@ -477,7 +477,7 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity) if (_set_->count != _new_set_->count) { hms_free(_new_set_); - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return 0; } struct hashmultiset_entry *tmp_b = _set_->buffer; @@ -500,7 +500,7 @@ struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) _set_->alloc, _set_->callbacks); if (!result) { - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (_set_->f_val->cpy) @@ -528,13 +528,13 @@ struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) sizeof(struct hashmultiset_entry) * _set_->capacity); result->count = _set_->count; result->cardinality = _set_->cardinality; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; return result; } _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { - _set1_->flag = cmc_flags.OK; - _set2_->flag = cmc_flags.OK; + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; if (_set1_->cardinality != _set2_->cardinality) @@ -557,10 +557,11 @@ struct cmc_string hms_to_string(struct hashmultiset *_set_) { struct cmc_string str; struct hashmultiset *s_ = _set_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmultiset, - "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, - s_->count, s_->cardinality, s_->load, s_->flag, s_->f_val, - s_->alloc, s_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmultiset, + "CMC_PARAM_SNAME((hms, hashmultiset, , , size_t))", + "CMC_PARAM_V((hms, hashmultiset, , , size_t))", s_, + s_->buffer, s_->capacity, s_->count, s_->cardinality, + s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool hms_print(struct hashmultiset *_set_, FILE *fptr) diff --git a/tests/main/src/hashset.c b/tests/main/src/hashset.c index 856920d..4f39d25 100644 --- a/tests/main/src/hashset.c +++ b/tests/main/src/hashset.c @@ -115,7 +115,7 @@ struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val) _set_->count = 0; _set_->capacity = real_capacity; _set_->load = load; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; _set_->callbacks = ((void *)0); @@ -147,7 +147,7 @@ struct hashset *hs_new_custom(size_t capacity, double load, _set_->count = 0; _set_->capacity = real_capacity; _set_->load = load; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; _set_->callbacks = callbacks; @@ -168,7 +168,7 @@ void hs_clear(struct hashset *_set_) } memset(_set_->buffer, 0, sizeof(struct hashset_entry) * _set_->capacity); _set_->count = 0; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; } void hs_free(struct hashset *_set_) { @@ -194,7 +194,7 @@ void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, else _set_->alloc = alloc; _set_->callbacks = callbacks; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; } _Bool hs_insert(struct hashset *_set_, size_t value) { @@ -205,7 +205,7 @@ _Bool hs_insert(struct hashset *_set_, size_t value) } if (hs_impl_get_entry(_set_, value) != ((void *)0)) { - _set_->flag = cmc_flags.DUPLICATE; + _set_->flag = CMC_FLAG_DUPLICATE; return 0; } size_t hash = _set_->f_val->hash(value); @@ -244,7 +244,7 @@ _Bool hs_insert(struct hashset *_set_, size_t value) } } _set_->count++; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->create) _set_->callbacks->create(); return 1; @@ -253,20 +253,20 @@ _Bool hs_remove(struct hashset *_set_, size_t value) { if (hs_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashset_entry *result = hs_impl_get_entry(_set_, value); if (result == ((void *)0)) { - _set_->flag = cmc_flags.NOT_FOUND; + _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } result->value = (size_t){ 0 }; result->dist = 0; result->state = CMC_ES_DELETED; _set_->count--; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->delete) _set_->callbacks->delete (); return 1; @@ -275,7 +275,7 @@ _Bool hs_max(struct hashset *_set_, size_t *value) { if (hs_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } size_t max_value; @@ -291,7 +291,7 @@ _Bool hs_max(struct hashset *_set_, size_t *value) } if (value) *value = max_value; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); return 1; @@ -300,7 +300,7 @@ _Bool hs_min(struct hashset *_set_, size_t *value) { if (hs_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } size_t min_value; @@ -316,14 +316,14 @@ _Bool hs_min(struct hashset *_set_, size_t *value) } if (value) *value = min_value; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); return 1; } _Bool hs_contains(struct hashset *_set_, size_t value) { - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; _Bool result = hs_impl_get_entry(_set_, value) != ((void *)0); if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); @@ -355,27 +355,27 @@ int hs_flag(struct hashset *_set_) } _Bool hs_resize(struct hashset *_set_, size_t capacity) { - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->capacity == capacity) goto success; if (_set_->capacity > capacity / _set_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _set_->load) { - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hs_impl_calculate_size(capacity); if (theoretical_size < _set_->count / _set_->load) { - _set_->flag = cmc_flags.INVALID; + _set_->flag = CMC_FLAG_INVALID; return 0; } struct hashset *_new_set_ = hs_new_custom( capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!_new_set_) { - _set_->flag = cmc_flags.ALLOC; + _set_->flag = CMC_FLAG_ALLOC; return 0; } struct hashset_iter iter = hs_iter_start(_set_); @@ -387,7 +387,7 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity) if (_set_->count != _new_set_->count) { hs_free(_new_set_); - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return 0; } struct hashset_entry *tmp_b = _set_->buffer; @@ -410,7 +410,7 @@ struct hashset *hs_copy_of(struct hashset *_set_) _set_->alloc, _set_->callbacks); if (!result) { - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (_set_->f_val->cpy) @@ -436,13 +436,13 @@ struct hashset *hs_copy_of(struct hashset *_set_) memcpy(result->buffer, _set_->buffer, sizeof(struct hashset_entry) * _set_->capacity); result->count = _set_->count; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; return result; } _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) { - _set1_->flag = cmc_flags.OK; - _set2_->flag = cmc_flags.OK; + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; if (_set1_->count == 0) @@ -459,9 +459,11 @@ struct cmc_string hs_to_string(struct hashset *_set_) { struct cmc_string str; struct hashset *s_ = _set_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashset, "hashset", - "size_t", s_, s_->buffer, s_->capacity, s_->count, - s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashset, + "CMC_PARAM_SNAME((hs, hashset, , , size_t))", + "CMC_PARAM_V((hs, hashset, , , size_t))", s_, s_->buffer, + s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, + s_->alloc, s_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool hs_print(struct hashset *_set_, FILE *fptr) @@ -484,8 +486,8 @@ struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) _set1_->alloc, ((void *)0)); if (!_set_r_) { - _set1_->flag = cmc_flags.ALLOC; - _set2_->flag = cmc_flags.ALLOC; + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter1 = hs_iter_start(_set1_); @@ -508,8 +510,8 @@ struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_) _set1_->alloc, ((void *)0)); if (!_set_r_) { - _set1_->flag = cmc_flags.ALLOC; - _set2_->flag = cmc_flags.ALLOC; + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; @@ -531,8 +533,8 @@ struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) _set1_->alloc, ((void *)0)); if (!_set_r_) { - _set1_->flag = cmc_flags.ALLOC; - _set2_->flag = cmc_flags.ALLOC; + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter = hs_iter_start(_set1_); @@ -553,8 +555,8 @@ struct hashset *hs_symmetric_difference(struct hashset *_set1_, _set1_->alloc, ((void *)0)); if (!_set_r_) { - _set1_->flag = cmc_flags.ALLOC; - _set2_->flag = cmc_flags.ALLOC; + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter1 = hs_iter_start(_set1_); @@ -576,8 +578,8 @@ struct hashset *hs_symmetric_difference(struct hashset *_set1_, } _Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_) { - _set1_->flag = cmc_flags.OK; - _set2_->flag = cmc_flags.OK; + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; if (_set1_->count > _set2_->count) return 0; if (hs_empty(_set1_)) @@ -597,8 +599,8 @@ _Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_) } _Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_) { - _set1_->flag = cmc_flags.OK; - _set2_->flag = cmc_flags.OK; + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; if (_set1_->count >= _set2_->count) return 0; if (hs_empty(_set1_)) @@ -623,8 +625,8 @@ _Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_) } _Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_) { - _set1_->flag = cmc_flags.OK; - _set2_->flag = cmc_flags.OK; + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; if (hs_empty(_set1_)) return 1; struct hashset_iter iter = hs_iter_start(_set1_); diff --git a/tests/main/src/heap.c b/tests/main/src/heap.c index 972af1d..fefc99f 100644 --- a/tests/main/src/heap.c +++ b/tests/main/src/heap.c @@ -90,7 +90,7 @@ struct heap *h_new(size_t capacity, enum cmc_heap_order HO, _heap_->capacity = capacity; _heap_->count = 0; _heap_->HO = HO; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; _heap_->callbacks = ((void *)0); @@ -120,7 +120,7 @@ struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, _heap_->capacity = capacity; _heap_->count = 0; _heap_->HO = HO; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; _heap_->callbacks = callbacks; @@ -137,7 +137,7 @@ void h_clear(struct heap *_heap_) } memset(_heap_->buffer, 0, sizeof(size_t) * _heap_->capacity); _heap_->count = 0; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; } void h_free(struct heap *_heap_) { @@ -159,7 +159,7 @@ void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, else _heap_->alloc = alloc; _heap_->callbacks = callbacks; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; } _Bool h_insert(struct heap *_heap_, size_t value) { @@ -173,7 +173,7 @@ _Bool h_insert(struct heap *_heap_, size_t value) { h_impl_float_up(_heap_, _heap_->count - 1); } - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->create) _heap_->callbacks->create(); return 1; @@ -182,14 +182,14 @@ _Bool h_remove(struct heap *_heap_) { if (h_empty(_heap_)) { - _heap_->flag = cmc_flags.EMPTY; + _heap_->flag = CMC_FLAG_EMPTY; return 0; } _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; _heap_->buffer[_heap_->count - 1] = (size_t){ 0 }; _heap_->count--; h_impl_float_down(_heap_, 0); - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->delete) _heap_->callbacks->delete (); return 1; @@ -198,17 +198,17 @@ size_t h_peek(struct heap *_heap_) { if (h_empty(_heap_)) { - _heap_->flag = cmc_flags.EMPTY; + _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->read) _heap_->callbacks->read(); return _heap_->buffer[0]; } _Bool h_contains(struct heap *_heap_, size_t value) { - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _heap_->count; i++) { @@ -244,19 +244,19 @@ int h_flag(struct heap *_heap_) } _Bool h_resize(struct heap *_heap_, size_t capacity) { - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->capacity == capacity) goto success; if (capacity < _heap_->count) { - _heap_->flag = cmc_flags.INVALID; + _heap_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { - _heap_->flag = cmc_flags.ALLOC; + _heap_->flag = CMC_FLAG_ALLOC; return 0; } _heap_->buffer = new_buffer; @@ -273,7 +273,7 @@ struct heap *h_copy_of(struct heap *_heap_) _heap_->callbacks); if (!result) { - _heap_->flag = cmc_flags.ERROR; + _heap_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (_heap_->f_val->cpy) @@ -284,13 +284,13 @@ struct heap *h_copy_of(struct heap *_heap_) else memcpy(result->buffer, _heap_->buffer, sizeof(size_t) * _heap_->count); result->count = _heap_->count; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; return result; } _Bool h_equals(struct heap *_heap1_, struct heap *_heap2_) { - _heap1_->flag = cmc_flags.OK; - _heap2_->flag = cmc_flags.OK; + _heap1_->flag = CMC_FLAG_OK; + _heap2_->flag = CMC_FLAG_OK; if (_heap1_->count != _heap2_->count) return 0; for (size_t i = 0; i < _heap1_->count; i++) @@ -305,9 +305,11 @@ struct cmc_string h_to_string(struct heap *_heap_) struct cmc_string str; struct heap *h_ = _heap_; const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_heap, "heap", - "size_t", h_, h_->buffer, h_->capacity, h_->count, t, - h_->flag, h_->f_val, h_->alloc, h_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_heap, + "CMC_PARAM_SNAME((h, heap, , , size_t))", + "CMC_PARAM_V((h, heap, , , size_t))", h_, h_->buffer, + h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, + h_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool h_print(struct heap *_heap_, FILE *fptr) diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index 568ac19..ddcce5b 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -94,7 +94,7 @@ struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) _heap_->capacity = capacity; _heap_->size = 0; _heap_->count = 0; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; _heap_->callbacks = ((void *)0); @@ -124,7 +124,7 @@ struct intervalheap *ih_new_custom(size_t capacity, _heap_->capacity = capacity; _heap_->size = 0; _heap_->count = 0; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; _heap_->callbacks = callbacks; @@ -142,7 +142,7 @@ void ih_clear(struct intervalheap *_heap_) memset(_heap_->buffer, 0, sizeof(size_t[2]) * _heap_->capacity); _heap_->size = 0; _heap_->count = 0; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; } void ih_free(struct intervalheap *_heap_) { @@ -164,7 +164,7 @@ void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, else _heap_->alloc = alloc; _heap_->callbacks = callbacks; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; } _Bool ih_insert(struct intervalheap *_heap_, size_t value) { @@ -193,7 +193,7 @@ _Bool ih_insert(struct intervalheap *_heap_, size_t value) } } _heap_->count++; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->count > 2) { size_t(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); @@ -210,7 +210,7 @@ _Bool ih_remove_max(struct intervalheap *_heap_) { if (ih_empty(_heap_)) { - _heap_->flag = cmc_flags.EMPTY; + _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) @@ -235,7 +235,7 @@ _Bool ih_remove_max(struct intervalheap *_heap_) _heap_->count--; ih_impl_float_down_max(_heap_); success: - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->delete) _heap_->callbacks->delete (); return 1; @@ -244,7 +244,7 @@ _Bool ih_remove_min(struct intervalheap *_heap_) { if (ih_empty(_heap_)) { - _heap_->flag = cmc_flags.EMPTY; + _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) @@ -269,7 +269,7 @@ _Bool ih_remove_min(struct intervalheap *_heap_) _heap_->count--; ih_impl_float_down_min(_heap_); success: - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->delete) _heap_->callbacks->delete (); return 1; @@ -278,7 +278,7 @@ _Bool ih_update_max(struct intervalheap *_heap_, size_t value) { if (ih_empty(_heap_)) { - _heap_->flag = cmc_flags.EMPTY; + _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) @@ -296,7 +296,7 @@ _Bool ih_update_max(struct intervalheap *_heap_, size_t value) _heap_->buffer[0][1] = value; ih_impl_float_down_max(_heap_); } - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->update) _heap_->callbacks->update(); return 1; @@ -305,7 +305,7 @@ _Bool ih_update_min(struct intervalheap *_heap_, size_t value) { if (ih_empty(_heap_)) { - _heap_->flag = cmc_flags.EMPTY; + _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) @@ -323,7 +323,7 @@ _Bool ih_update_min(struct intervalheap *_heap_, size_t value) _heap_->buffer[0][0] = value; ih_impl_float_down_min(_heap_); } - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->update) _heap_->callbacks->update(); return 1; @@ -332,10 +332,10 @@ size_t ih_max(struct intervalheap *_heap_) { if (ih_empty(_heap_)) { - _heap_->flag = cmc_flags.EMPTY; + _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->read) _heap_->callbacks->read(); if (_heap_->count == 1) @@ -346,17 +346,17 @@ size_t ih_min(struct intervalheap *_heap_) { if (ih_empty(_heap_)) { - _heap_->flag = cmc_flags.EMPTY; + _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->read) _heap_->callbacks->read(); return _heap_->buffer[0][0]; } _Bool ih_contains(struct intervalheap *_heap_, size_t value) { - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _heap_->count; i++) { @@ -396,12 +396,12 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity) goto success; if (capacity < _heap_->count) { - _heap_->flag = cmc_flags.INVALID; + _heap_->flag = CMC_FLAG_INVALID; return 0; } if (capacity == 0xffffffffffffffffULL) { - _heap_->flag = cmc_flags.ERROR; + _heap_->flag = CMC_FLAG_ERROR; return 0; } capacity += capacity % 2; @@ -409,7 +409,7 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity) _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity); if (!new_buffer) { - _heap_->flag = cmc_flags.ALLOC; + _heap_->flag = CMC_FLAG_ALLOC; return 0; } if (capacity > _heap_->capacity) @@ -420,7 +420,7 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity) _heap_->buffer = new_buffer; _heap_->capacity = capacity; success: - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; if (_heap_->callbacks && _heap_->callbacks->resize) _heap_->callbacks->resize(); return 1; @@ -431,7 +431,7 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_) _heap_->alloc->malloc(sizeof(struct intervalheap)); if (!result) { - _heap_->flag = cmc_flags.ALLOC; + _heap_->flag = CMC_FLAG_ALLOC; return ((void *)0); } memcpy(result, _heap_, sizeof(struct intervalheap)); @@ -440,7 +440,7 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_) if (!result->buffer) { _heap_->alloc->free(result); - _heap_->flag = cmc_flags.ALLOC; + _heap_->flag = CMC_FLAG_ALLOC; return ((void *)0); } if (_heap_->f_val->cpy) @@ -455,17 +455,17 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_) result->capacity = _heap_->capacity; result->size = _heap_->size; result->count = _heap_->count; - result->flag = cmc_flags.OK; + result->flag = CMC_FLAG_OK; result->f_val = _heap_->f_val; result->alloc = _heap_->alloc; result->callbacks = _heap_->callbacks; - _heap_->flag = cmc_flags.OK; + _heap_->flag = CMC_FLAG_OK; return result; } _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_) { - _heap1_->flag = cmc_flags.OK; - _heap2_->flag = cmc_flags.OK; + _heap1_->flag = CMC_FLAG_OK; + _heap2_->flag = CMC_FLAG_OK; if (_heap1_->count != _heap2_->count) return 0; for (size_t i = 0; i < _heap1_->count; i++) @@ -481,10 +481,11 @@ struct cmc_string ih_to_string(struct intervalheap *_heap_) { struct cmc_string str; struct intervalheap *h_ = _heap_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_intervalheap, - "intervalheap", "size_t", h_, h_->buffer, h_->capacity, - h_->size, h_->count, h_->flag, h_->f_val, h_->alloc, - h_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_intervalheap, + "CMC_PARAM_SNAME((ih, intervalheap, , , size_t))", + "CMC_PARAM_V((ih, intervalheap, , , size_t))", h_, + h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, + h_->f_val, h_->alloc, h_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool ih_print(struct intervalheap *_heap_, FILE *fptr) diff --git a/tests/main/src/linkedlist.c b/tests/main/src/linkedlist.c index f5d3d6a..acf7384 100644 --- a/tests/main/src/linkedlist.c +++ b/tests/main/src/linkedlist.c @@ -102,7 +102,7 @@ struct linkedlist *ll_new(struct linkedlist_fval *f_val) _list_->count = 0; _list_->head = ((void *)0); _list_->tail = ((void *)0); - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; _list_->callbacks = ((void *)0); @@ -122,7 +122,7 @@ struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, _list_->count = 0; _list_->head = ((void *)0); _list_->tail = ((void *)0); - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; _list_->callbacks = callbacks; @@ -144,7 +144,7 @@ void ll_clear(struct linkedlist *_list_) _list_->count = 0; _list_->head = ((void *)0); _list_->tail = ((void *)0); - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; } void ll_free(struct linkedlist *_list_) { @@ -159,7 +159,7 @@ void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, else _list_->alloc = alloc; _list_->callbacks = callbacks; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; } _Bool ll_push_front(struct linkedlist *_list_, size_t value) { @@ -178,7 +178,7 @@ _Bool ll_push_front(struct linkedlist *_list_, size_t value) _list_->head = _node_; } _list_->count++; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -187,7 +187,7 @@ _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) { if (index > _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) @@ -207,7 +207,7 @@ _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) _node_->next->prev = _node_; _node_->prev->next = _node_; _list_->count++; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -229,7 +229,7 @@ _Bool ll_push_back(struct linkedlist *_list_, size_t value) _list_->tail = _node_; } _list_->count++; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -238,7 +238,7 @@ _Bool ll_pop_front(struct linkedlist *_list_) { if (ll_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return 0; } struct linkedlist_node *_node_ = _list_->head; @@ -249,7 +249,7 @@ _Bool ll_pop_front(struct linkedlist *_list_) else _list_->head->prev = ((void *)0); _list_->count--; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return 1; @@ -258,12 +258,12 @@ _Bool ll_pop_at(struct linkedlist *_list_, size_t index) { if (ll_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) @@ -281,7 +281,7 @@ _Bool ll_pop_at(struct linkedlist *_list_, size_t index) _node_->prev->next = _node_->next; _list_->alloc->free(_node_); _list_->count--; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return 1; @@ -290,7 +290,7 @@ _Bool ll_pop_back(struct linkedlist *_list_) { if (ll_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return 0; } struct linkedlist_node *_node_ = _list_->tail; @@ -301,7 +301,7 @@ _Bool ll_pop_back(struct linkedlist *_list_) else _list_->tail->next = ((void *)0); _list_->count--; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return 1; @@ -310,10 +310,10 @@ size_t ll_front(struct linkedlist *_list_) { if (ll_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return _list_->head->value; @@ -322,12 +322,12 @@ size_t ll_get(struct linkedlist *_list_, size_t index) { if (ll_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } struct linkedlist_node *scan = ll_get_node(_list_, index); @@ -341,12 +341,12 @@ size_t *ll_get_ref(struct linkedlist *_list_, size_t index) { if (ll_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } struct linkedlist_node *scan = ll_get_node(_list_, index); @@ -360,17 +360,17 @@ size_t ll_back(struct linkedlist *_list_) { if (ll_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return _list_->tail->value; } _Bool ll_contains(struct linkedlist *_list_, size_t value) { - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; _Bool result = 0; struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) @@ -426,13 +426,13 @@ struct linkedlist *ll_copy_of(struct linkedlist *_list_) scan = scan->next; } result->count = _list_->count; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; return result; } _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) { - _list1_->flag = cmc_flags.OK; - _list2_->flag = cmc_flags.OK; + _list1_->flag = CMC_FLAG_OK; + _list2_->flag = CMC_FLAG_OK; if (_list1_->count != _list2_->count) return 0; struct linkedlist_node *scan1 = _list1_->head; @@ -450,9 +450,11 @@ struct cmc_string ll_to_string(struct linkedlist *_list_) { struct cmc_string str; struct linkedlist *l_ = _list_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_linkedlist, - "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, - l_->flag, l_->f_val, l_->alloc, l_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_linkedlist, + "CMC_PARAM_SNAME((ll, linkedlist, , , size_t))", + "CMC_PARAM_V((ll, linkedlist, , , size_t))", l_, l_->count, + l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, + l_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool ll_print(struct linkedlist *_list_, FILE *fptr) @@ -472,7 +474,7 @@ struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) _list_->alloc->malloc(sizeof(struct linkedlist_node)); if (!_node_) { - _list_->flag = cmc_flags.ALLOC; + _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } _node_->value = value; @@ -492,12 +494,12 @@ struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index) { if (ll_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } struct linkedlist_node *_node_ = ((void *)0); @@ -517,7 +519,7 @@ struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index) _node_ = _node_->prev; } } - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; return _node_; } struct linkedlist_node *ll_tail(struct linkedlist *_list_) @@ -538,7 +540,7 @@ _Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, new_node->prev = _node_; _node_->next = new_node; _owner_->count++; - _owner_->flag = cmc_flags.OK; + _owner_->flag = CMC_FLAG_OK; return 1; } _Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, @@ -555,14 +557,14 @@ _Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, new_node->next = _node_; _node_->prev = new_node; _owner_->count++; - _owner_->flag = cmc_flags.OK; + _owner_->flag = CMC_FLAG_OK; return 1; } _Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_) { if (_node_->next == ((void *)0)) { - _owner_->flag = cmc_flags.INVALID; + _owner_->flag = CMC_FLAG_INVALID; return 0; } struct linkedlist_node *tmp = _node_->next; @@ -573,7 +575,7 @@ _Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_) _owner_->tail = _node_; _owner_->alloc->free(tmp); _owner_->count--; - _owner_->flag = cmc_flags.OK; + _owner_->flag = CMC_FLAG_OK; return 1; } _Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_) @@ -588,14 +590,14 @@ _Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_) _owner_->tail = _node_->prev; _owner_->alloc->free(_node_); _owner_->count--; - _owner_->flag = cmc_flags.OK; + _owner_->flag = CMC_FLAG_OK; return 1; } _Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_) { if (_node_->prev == ((void *)0)) { - _owner_->flag = cmc_flags.INVALID; + _owner_->flag = CMC_FLAG_INVALID; return 0; } struct linkedlist_node *tmp = _node_->prev; @@ -606,7 +608,7 @@ _Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_) _owner_->head = _node_; _owner_->alloc->free(tmp); _owner_->count--; - _owner_->flag = cmc_flags.OK; + _owner_->flag = CMC_FLAG_OK; return 1; } struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_) diff --git a/tests/main/src/list.c b/tests/main/src/list.c index 221171c..b0e8824 100644 --- a/tests/main/src/list.c +++ b/tests/main/src/list.c @@ -96,7 +96,7 @@ struct list *l_new(size_t capacity, struct list_fval *f_val) } _list_->capacity = capacity; _list_->count = 0; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; _list_->callbacks = ((void *)0); @@ -123,7 +123,7 @@ struct list *l_new_custom(size_t capacity, struct list_fval *f_val, } _list_->capacity = capacity; _list_->count = 0; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; _list_->callbacks = callbacks; @@ -138,7 +138,7 @@ void l_clear(struct list *_list_) } memset(_list_->buffer, 0, sizeof(size_t) * _list_->capacity); _list_->count = 0; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; } void l_free(struct list *_list_) { @@ -158,7 +158,7 @@ void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, else _list_->alloc = alloc; _list_->callbacks = callbacks; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; } _Bool l_push_front(struct list *_list_, size_t value) { @@ -174,7 +174,7 @@ _Bool l_push_front(struct list *_list_, size_t value) } _list_->buffer[0] = value; _list_->count++; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -183,7 +183,7 @@ _Bool l_push_at(struct list *_list_, size_t value, size_t index) { if (index > _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return 0; } if (l_full(_list_)) @@ -195,7 +195,7 @@ _Bool l_push_at(struct list *_list_, size_t value, size_t index) (_list_->count - index) * sizeof(size_t)); _list_->buffer[index] = value; _list_->count++; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -208,7 +208,7 @@ _Bool l_push_back(struct list *_list_, size_t value) return 0; } _list_->buffer[_list_->count++] = value; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -217,13 +217,13 @@ _Bool l_pop_front(struct list *_list_) { if (l_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return 0; } memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return 1; @@ -232,18 +232,18 @@ _Bool l_pop_at(struct list *_list_, size_t index) { if (l_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return 0; } memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return 1; @@ -253,7 +253,7 @@ _Bool l_pop_back(struct list *_list_) if (l_empty(_list_)) return 0; _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return 1; @@ -262,7 +262,7 @@ _Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) { if (size == 0) { - _list_->flag = cmc_flags.INVALID; + _list_->flag = CMC_FLAG_INVALID; return 0; } if (!l_fits(_list_, size)) @@ -274,7 +274,7 @@ _Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) _list_->count * sizeof(size_t)); memcpy(_list_->buffer, values, size * sizeof(size_t)); _list_->count += size; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -284,12 +284,12 @@ _Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, { if (size == 0) { - _list_->flag = cmc_flags.INVALID; + _list_->flag = CMC_FLAG_INVALID; return 0; } if (index > _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) @@ -305,7 +305,7 @@ _Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, (_list_->count - index) * sizeof(size_t)); memcpy(_list_->buffer + index, values, size * sizeof(size_t)); _list_->count += size; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -314,7 +314,7 @@ _Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) { if (size == 0) { - _list_->flag = cmc_flags.INVALID; + _list_->flag = CMC_FLAG_INVALID; return 0; } if (!l_fits(_list_, size)) @@ -324,7 +324,7 @@ _Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) } memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); _list_->count += size; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -333,12 +333,12 @@ _Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) { if (from > to) { - _list_->flag = cmc_flags.INVALID; + _list_->flag = CMC_FLAG_INVALID; return 0; } if (to >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return 0; } size_t length = (to - from + 1); @@ -346,7 +346,7 @@ _Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) (_list_->count - to - 1) * sizeof(size_t)); memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); _list_->count -= to - from + 1; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return 1; @@ -355,12 +355,12 @@ struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) { if (from > to) { - _list_->flag = cmc_flags.INVALID; + _list_->flag = CMC_FLAG_INVALID; return ((void *)0); } if (to >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } size_t length = to - from + 1; @@ -368,7 +368,7 @@ struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) l_new_custom(length, _list_->f_val, _list_->alloc, _list_->callbacks); if (!result) { - _list_->flag = cmc_flags.ALLOC; + _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); @@ -377,7 +377,7 @@ struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); _list_->count -= length; result->count = length; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return result; @@ -386,10 +386,10 @@ size_t l_front(struct list *_list_) { if (l_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return _list_->buffer[0]; @@ -398,15 +398,15 @@ size_t l_get(struct list *_list_, size_t index) { if (l_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return _list_->buffer[index]; @@ -415,15 +415,15 @@ size_t *l_get_ref(struct list *_list_, size_t index) { if (l_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return &(_list_->buffer[index]); @@ -432,17 +432,17 @@ size_t l_back(struct list *_list_) { if (l_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return _list_->buffer[_list_->count - 1]; } size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) { - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; size_t result = _list_->count; if (from_start) { @@ -472,7 +472,7 @@ size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) } _Bool l_contains(struct list *_list_, size_t value) { - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _list_->count; i++) { @@ -512,19 +512,19 @@ int l_flag(struct list *_list_) } _Bool l_resize(struct list *_list_, size_t capacity) { - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->capacity == capacity) return 1; if (capacity < _list_->count) { - _list_->flag = cmc_flags.INVALID; + _list_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { - _list_->flag = cmc_flags.ALLOC; + _list_->flag = CMC_FLAG_ALLOC; return 0; } _list_->buffer = new_buffer; @@ -539,7 +539,7 @@ struct list *l_copy_of(struct list *_list_) _list_->alloc, _list_->callbacks); if (!result) { - _list_->flag = cmc_flags.ALLOC; + _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } if (_list_->f_val->cpy) @@ -550,13 +550,13 @@ struct list *l_copy_of(struct list *_list_) else memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); result->count = _list_->count; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; return result; } _Bool l_equals(struct list *_list1_, struct list *_list2_) { - _list1_->flag = cmc_flags.OK; - _list2_->flag = cmc_flags.OK; + _list1_->flag = CMC_FLAG_OK; + _list2_->flag = CMC_FLAG_OK; if (_list1_->count != _list2_->count) return 0; for (size_t i = 0; i < _list1_->count; i++) @@ -570,9 +570,11 @@ struct cmc_string l_to_string(struct list *_list_) { struct cmc_string str; struct list *l_ = _list_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_list, "list", - "size_t", l_, l_->buffer, l_->capacity, l_->count, - l_->flag, l_->f_val, l_->alloc, l_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_list, + "CMC_PARAM_SNAME((l, list, , , size_t))", + "CMC_PARAM_V((l, list, , , size_t))", l_, l_->buffer, + l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, + l_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool l_print(struct list *_list_, FILE *fptr) diff --git a/tests/main/src/queue.c b/tests/main/src/queue.c index f749065..73abdce 100644 --- a/tests/main/src/queue.c +++ b/tests/main/src/queue.c @@ -88,7 +88,7 @@ struct queue *q_new(size_t capacity, struct queue_fval *f_val) _queue_->count = 0; _queue_->front = 0; _queue_->back = 0; - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; _queue_->f_val = f_val; _queue_->alloc = alloc; _queue_->callbacks = ((void *)0); @@ -117,7 +117,7 @@ struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, _queue_->count = 0; _queue_->front = 0; _queue_->back = 0; - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; _queue_->f_val = f_val; _queue_->alloc = alloc; _queue_->callbacks = callbacks; @@ -137,7 +137,7 @@ void q_clear(struct queue *_queue_) _queue_->count = 0; _queue_->front = 0; _queue_->back = 0; - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; } void q_free(struct queue *_queue_) { @@ -160,7 +160,7 @@ void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, else _queue_->alloc = alloc; _queue_->callbacks = callbacks; - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; } _Bool q_enqueue(struct queue *_queue_, size_t value) { @@ -173,7 +173,7 @@ _Bool q_enqueue(struct queue *_queue_, size_t value) _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; _queue_->count++; - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; if (_queue_->callbacks && _queue_->callbacks->create) _queue_->callbacks->create(); return 1; @@ -182,14 +182,14 @@ _Bool q_dequeue(struct queue *_queue_) { if (q_empty(_queue_)) { - _queue_->flag = cmc_flags.EMPTY; + _queue_->flag = CMC_FLAG_EMPTY; return 0; } _queue_->buffer[_queue_->front] = (size_t){ 0 }; _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; _queue_->count--; - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; if (_queue_->callbacks && _queue_->callbacks->delete) _queue_->callbacks->delete (); return 1; @@ -198,17 +198,17 @@ size_t q_peek(struct queue *_queue_) { if (q_empty(_queue_)) { - _queue_->flag = cmc_flags.EMPTY; + _queue_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; if (_queue_->callbacks && _queue_->callbacks->read) _queue_->callbacks->read(); return _queue_->buffer[_queue_->front]; } _Bool q_contains(struct queue *_queue_, size_t value) { - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) { @@ -249,13 +249,13 @@ _Bool q_resize(struct queue *_queue_, size_t capacity) goto success; if (capacity < _queue_->count) { - _queue_->flag = cmc_flags.INVALID; + _queue_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _queue_->alloc->malloc(sizeof(size_t) * capacity); if (!new_buffer) { - _queue_->flag = cmc_flags.ALLOC; + _queue_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) @@ -269,7 +269,7 @@ _Bool q_resize(struct queue *_queue_, size_t capacity) _queue_->front = 0; _queue_->back = _queue_->count; success: - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; if (_queue_->callbacks && _queue_->callbacks->resize) _queue_->callbacks->resize(); return 1; @@ -280,7 +280,7 @@ struct queue *q_copy_of(struct queue *_queue_) _queue_->alloc, _queue_->callbacks); if (!result) { - _queue_->flag = cmc_flags.ERROR; + _queue_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (_queue_->f_val->cpy) @@ -302,13 +302,13 @@ struct queue *q_copy_of(struct queue *_queue_) result->count = _queue_->count; result->front = 0; result->back = _queue_->count; - _queue_->flag = cmc_flags.OK; + _queue_->flag = CMC_FLAG_OK; return result; } _Bool q_equals(struct queue *_queue1_, struct queue *_queue2_) { - _queue1_->flag = cmc_flags.OK; - _queue2_->flag = cmc_flags.OK; + _queue1_->flag = CMC_FLAG_OK; + _queue2_->flag = CMC_FLAG_OK; if (_queue1_->count != _queue2_->count) return 0; size_t i, j, k; @@ -326,10 +326,11 @@ struct cmc_string q_to_string(struct queue *_queue_) { struct cmc_string str; struct queue *q_ = _queue_; - int n = - snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, "queue", "size_t", - q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, - q_->flag, q_->f_val, q_->alloc, q_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_queue, + "CMC_PARAM_SNAME((q, queue, , , size_t))", + "CMC_PARAM_V((q, queue, , , size_t))", q_, q_->buffer, + q_->capacity, q_->count, q_->front, q_->back, q_->flag, + q_->f_val, q_->alloc, q_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool q_print(struct queue *_queue_, FILE *fptr) diff --git a/tests/main/src/sortedlist.c b/tests/main/src/sortedlist.c index efa0d92..61c1141 100644 --- a/tests/main/src/sortedlist.c +++ b/tests/main/src/sortedlist.c @@ -96,7 +96,7 @@ struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val) _list_->capacity = capacity; _list_->count = 0; _list_->is_sorted = 0; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; _list_->callbacks = ((void *)0); @@ -122,7 +122,7 @@ struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, _list_->capacity = capacity; _list_->count = 0; _list_->is_sorted = 0; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; _list_->callbacks = callbacks; @@ -137,7 +137,7 @@ void sl_clear(struct sortedlist *_list_) } memset(_list_->buffer, 0, sizeof(size_t) * _list_->capacity); _list_->count = 0; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; } void sl_free(struct sortedlist *_list_) { @@ -157,7 +157,7 @@ void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, else _list_->alloc = alloc; _list_->callbacks = callbacks; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; } _Bool sl_insert(struct sortedlist *_list_, size_t value) { @@ -168,7 +168,7 @@ _Bool sl_insert(struct sortedlist *_list_, size_t value) } _list_->buffer[_list_->count++] = value; _list_->is_sorted = 0; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->create) _list_->callbacks->create(); return 1; @@ -177,18 +177,18 @@ _Bool sl_remove(struct sortedlist *_list_, size_t index) { if (sl_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return 0; } memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) _list_->callbacks->delete (); return 1; @@ -197,11 +197,11 @@ size_t sl_max(struct sortedlist *_list_) { if (sl_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } sl_sort(_list_); - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return _list_->buffer[_list_->count - 1]; @@ -210,11 +210,11 @@ size_t sl_min(struct sortedlist *_list_) { if (sl_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } sl_sort(_list_); - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return _list_->buffer[0]; @@ -223,23 +223,23 @@ size_t sl_get(struct sortedlist *_list_, size_t index) { if (sl_empty(_list_)) { - _list_->flag = cmc_flags.EMPTY; + _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { - _list_->flag = cmc_flags.RANGE; + _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } sl_sort(_list_); - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); return _list_->buffer[index]; } size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start) { - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; sl_sort(_list_); if (_list_->callbacks && _list_->callbacks->read) _list_->callbacks->read(); @@ -251,7 +251,7 @@ size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start) } _Bool sl_contains(struct sortedlist *_list_, size_t value) { - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (sl_empty(_list_)) return 0; sl_sort(_list_); @@ -285,27 +285,27 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity) goto success; if (capacity < _list_->count) { - _list_->flag = cmc_flags.INVALID; + _list_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { - _list_->flag = cmc_flags.ALLOC; + _list_->flag = CMC_FLAG_ALLOC; return 0; } _list_->buffer = new_buffer; _list_->capacity = capacity; success: - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->resize) _list_->callbacks->resize(); return 1; } void sl_sort(struct sortedlist *_list_) { - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; if (!_list_->is_sorted && _list_->count > 1) { sl_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, @@ -319,7 +319,7 @@ struct sortedlist *sl_copy_of(struct sortedlist *_list_) _list_->alloc, _list_->callbacks); if (!result) { - _list_->flag = cmc_flags.ERROR; + _list_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (_list_->f_val->cpy) @@ -330,7 +330,7 @@ struct sortedlist *sl_copy_of(struct sortedlist *_list_) else memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); result->count = _list_->count; - _list_->flag = cmc_flags.OK; + _list_->flag = CMC_FLAG_OK; return result; } _Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_) @@ -350,10 +350,12 @@ struct cmc_string sl_to_string(struct sortedlist *_list_) { struct cmc_string str; struct sortedlist *l_ = _list_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_sortedlist, - "sortedlist", "size_t", l_, l_->buffer, l_->capacity, - l_->count, l_->is_sorted ? "true" : "false", l_->flag, - l_->f_val, l_->alloc, l_->callbacks); + int n = + snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_sortedlist, + "CMC_PARAM_SNAME((sl, sortedlist, , , size_t))", + "CMC_PARAM_V((sl, sortedlist, , , size_t))", l_, l_->buffer, + l_->capacity, l_->count, l_->is_sorted ? "true" : "false", + l_->flag, l_->f_val, l_->alloc, l_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool sl_print(struct sortedlist *_list_, FILE *fptr) diff --git a/tests/main/src/stack.c b/tests/main/src/stack.c index a0be8dd..b98f023 100644 --- a/tests/main/src/stack.c +++ b/tests/main/src/stack.c @@ -83,7 +83,7 @@ struct stack *s_new(size_t capacity, struct stack_fval *f_val) } _stack_->capacity = capacity; _stack_->count = 0; - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; _stack_->f_val = f_val; _stack_->alloc = alloc; _stack_->callbacks = ((void *)0); @@ -110,7 +110,7 @@ struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, } _stack_->capacity = capacity; _stack_->count = 0; - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; _stack_->f_val = f_val; _stack_->alloc = alloc; _stack_->callbacks = callbacks; @@ -125,7 +125,7 @@ void s_clear(struct stack *_stack_) } memset(_stack_->buffer, 0, sizeof(size_t) * _stack_->capacity); _stack_->count = 0; - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; } void s_free(struct stack *_stack_) { @@ -145,7 +145,7 @@ void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, else _stack_->alloc = alloc; _stack_->callbacks = callbacks; - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; } _Bool s_push(struct stack *_stack_, size_t value) { @@ -155,7 +155,7 @@ _Bool s_push(struct stack *_stack_, size_t value) return 0; } _stack_->buffer[_stack_->count++] = value; - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; if (_stack_->callbacks && _stack_->callbacks->create) _stack_->callbacks->create(); return 1; @@ -164,11 +164,11 @@ _Bool s_pop(struct stack *_stack_) { if (s_empty(_stack_)) { - _stack_->flag = cmc_flags.EMPTY; + _stack_->flag = CMC_FLAG_EMPTY; return 0; } _stack_->buffer[--_stack_->count] = (size_t){ 0 }; - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; if (_stack_->callbacks && _stack_->callbacks->delete) _stack_->callbacks->delete (); return 1; @@ -177,17 +177,17 @@ size_t s_top(struct stack *_stack_) { if (s_empty(_stack_)) { - _stack_->flag = cmc_flags.EMPTY; + _stack_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; if (_stack_->callbacks && _stack_->callbacks->read) _stack_->callbacks->read(); return _stack_->buffer[_stack_->count - 1]; } _Bool s_contains(struct stack *_stack_, size_t value) { - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _stack_->count; i++) { @@ -227,20 +227,20 @@ _Bool s_resize(struct stack *_stack_, size_t capacity) goto success; if (capacity < _stack_->count) { - _stack_->flag = cmc_flags.INVALID; + _stack_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { - _stack_->flag = cmc_flags.ALLOC; + _stack_->flag = CMC_FLAG_ALLOC; return 0; } _stack_->buffer = new_buffer; _stack_->capacity = capacity; success: - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; if (_stack_->callbacks && _stack_->callbacks->resize) _stack_->callbacks->resize(); return 1; @@ -251,7 +251,7 @@ struct stack *s_copy_of(struct stack *_stack_) _stack_->alloc, _stack_->callbacks); if (!result) { - _stack_->flag = cmc_flags.ERROR; + _stack_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (_stack_->f_val->cpy) @@ -263,13 +263,13 @@ struct stack *s_copy_of(struct stack *_stack_) memcpy(result->buffer, _stack_->buffer, sizeof(size_t) * _stack_->count); result->count = _stack_->count; - _stack_->flag = cmc_flags.OK; + _stack_->flag = CMC_FLAG_OK; return result; } _Bool s_equals(struct stack *_stack1_, struct stack *_stack2_) { - _stack1_->flag = cmc_flags.OK; - _stack2_->flag = cmc_flags.OK; + _stack1_->flag = CMC_FLAG_OK; + _stack2_->flag = CMC_FLAG_OK; if (_stack1_->count != _stack2_->count) return 0; for (size_t i = 0; i < _stack1_->count; i++) @@ -283,9 +283,11 @@ struct cmc_string s_to_string(struct stack *_stack_) { struct cmc_string str; struct stack *s_ = _stack_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, "stack", - "size_t", s_, s_->buffer, s_->capacity, s_->count, - s_->flag, s_->f_val, s_->alloc, s_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_stack, + "CMC_PARAM_SNAME((s, stack, , , size_t))", + "CMC_PARAM_V((s, stack, , , size_t))", s_, s_->buffer, + s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, + s_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool s_print(struct stack *_stack_, FILE *fptr) diff --git a/tests/main/src/treemap.c b/tests/main/src/treemap.c index f30a722..66d955f 100644 --- a/tests/main/src/treemap.c +++ b/tests/main/src/treemap.c @@ -108,7 +108,7 @@ struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val) return ((void *)0); _map_->count = 0; _map_->root = ((void *)0); - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; @@ -129,7 +129,7 @@ struct treemap *tm_new_custom(struct treemap_fkey *f_key, return ((void *)0); _map_->count = 0; _map_->root = ((void *)0); - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; @@ -191,7 +191,7 @@ void tm_clear(struct treemap *_map_) } _map_->count = 0; _map_->root = ((void *)0); - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; } void tm_free(struct treemap *_map_) { @@ -206,7 +206,7 @@ void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, else _map_->alloc = alloc; _map_->callbacks = callbacks; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; } _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) { @@ -215,7 +215,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) _map_->root = tm_impl_new_node(_map_, key, value); if (!_map_->root) { - _map_->flag = cmc_flags.ALLOC; + _map_->flag = CMC_FLAG_ALLOC; return 0; } } @@ -232,7 +232,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) scan = scan->right; else { - _map_->flag = cmc_flags.DUPLICATE; + _map_->flag = CMC_FLAG_DUPLICATE; return 0; } } @@ -242,7 +242,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) parent->left = tm_impl_new_node(_map_, key, value); if (!parent->left) { - _map_->flag = cmc_flags.ALLOC; + _map_->flag = CMC_FLAG_ALLOC; return 0; } parent->left->parent = parent; @@ -253,7 +253,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) parent->right = tm_impl_new_node(_map_, key, value); if (!parent->right) { - _map_->flag = cmc_flags.ALLOC; + _map_->flag = CMC_FLAG_ALLOC; return 0; } parent->right->parent = parent; @@ -262,7 +262,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) tm_impl_rebalance(_map_, node); } _map_->count++; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->create) _map_->callbacks->create(); return 1; @@ -273,13 +273,13 @@ _Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (old_value) *old_value = node->value; node->value = new_value; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->update) _map_->callbacks->update(); return 1; @@ -288,13 +288,13 @@ _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) { if (tm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_value) @@ -391,7 +391,7 @@ _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) if (_map_->count == 0) _map_->root = ((void *)0); _map_->count--; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->delete) _map_->callbacks->delete (); return 1; @@ -400,7 +400,7 @@ _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) { if (tm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *scan = _map_->root; @@ -410,7 +410,7 @@ _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) *key = scan->key; if (value) *value = scan->value; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return 1; @@ -419,7 +419,7 @@ _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) { if (tm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *scan = _map_->root; @@ -429,7 +429,7 @@ _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) *key = scan->key; if (value) *value = scan->value; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return 1; @@ -438,16 +438,16 @@ size_t tm_get(struct treemap *_map_, size_t key) { if (tm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return node->value; @@ -456,16 +456,16 @@ size_t *tm_get_ref(struct treemap *_map_, size_t key) { if (tm_empty(_map_)) { - _map_->flag = cmc_flags.EMPTY; + _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { - _map_->flag = cmc_flags.NOT_FOUND; + _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; if (_map_->callbacks && _map_->callbacks->read) _map_->callbacks->read(); return &(node->value); @@ -495,7 +495,7 @@ struct treemap *tm_copy_of(struct treemap *_map_) tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { - _map_->flag = cmc_flags.ERROR; + _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } struct treemap_iter iter = tm_iter_start(_map_); @@ -510,13 +510,13 @@ struct treemap *tm_copy_of(struct treemap *_map_) tm_insert(result, key, value); } result->callbacks = _map_->callbacks; - _map_->flag = cmc_flags.OK; + _map_->flag = CMC_FLAG_OK; return result; } _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) { - _map1_->flag = cmc_flags.OK; - _map2_->flag = cmc_flags.OK; + _map1_->flag = CMC_FLAG_OK; + _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct treemap_iter iter = tm_iter_start(_map1_); @@ -535,9 +535,12 @@ struct cmc_string tm_to_string(struct treemap *_map_) { struct cmc_string str; struct treemap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_treemap, "treemap", - "size_t", "size_t", m_, m_->root, m_->count, m_->flag, - m_->f_key, m_->f_val, m_->alloc, m_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treemap, + "CMC_PARAM_SNAME((tm, treemap, , size_t, size_t))", + "CMC_PARAM_K((tm, treemap, , size_t, size_t))", + "CMC_PARAM_V((tm, treemap, , size_t, size_t))", m_, + m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, + m_->alloc, m_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool tm_print(struct treemap *_map_, FILE *fptr) diff --git a/tests/main/src/treeset.c b/tests/main/src/treeset.c index 517b40a..9952dc2 100644 --- a/tests/main/src/treeset.c +++ b/tests/main/src/treeset.c @@ -107,7 +107,7 @@ struct treeset *ts_new(struct treeset_fval *f_val) return ((void *)0); _set_->count = 0; _set_->root = ((void *)0); - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; _set_->callbacks = ((void *)0); @@ -126,7 +126,7 @@ struct treeset *ts_new_custom(struct treeset_fval *f_val, return ((void *)0); _set_->count = 0; _set_->root = ((void *)0); - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; _set_->callbacks = callbacks; @@ -183,7 +183,7 @@ void ts_clear(struct treeset *_set_) } _set_->count = 0; _set_->root = ((void *)0); - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; } void ts_free(struct treeset *_set_) { @@ -198,7 +198,7 @@ void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, else _set_->alloc = alloc; _set_->callbacks = callbacks; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; } _Bool ts_insert(struct treeset *_set_, size_t value) { @@ -207,7 +207,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value) _set_->root = ts_impl_new_node(_set_, value); if (!_set_->root) { - _set_->flag = cmc_flags.ALLOC; + _set_->flag = CMC_FLAG_ALLOC; return 0; } } @@ -224,7 +224,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value) scan = scan->right; else { - _set_->flag = cmc_flags.DUPLICATE; + _set_->flag = CMC_FLAG_DUPLICATE; return 0; } } @@ -234,7 +234,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value) parent->left = ts_impl_new_node(_set_, value); if (!parent->left) { - _set_->flag = cmc_flags.ALLOC; + _set_->flag = CMC_FLAG_ALLOC; return 0; } parent->left->parent = parent; @@ -245,7 +245,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value) parent->right = ts_impl_new_node(_set_, value); if (!parent->right) { - _set_->flag = cmc_flags.ALLOC; + _set_->flag = CMC_FLAG_ALLOC; return 0; } parent->right->parent = parent; @@ -254,7 +254,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value) ts_impl_rebalance(_set_, node); } _set_->count++; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->create) _set_->callbacks->create(); return 1; @@ -263,13 +263,13 @@ _Bool ts_remove(struct treeset *_set_, size_t value) { if (ts_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *node = ts_impl_get_node(_set_, value); if (!node) { - _set_->flag = cmc_flags.NOT_FOUND; + _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } struct treeset_node *temp = ((void *)0), *unbalanced = ((void *)0); @@ -362,7 +362,7 @@ _Bool ts_remove(struct treeset *_set_, size_t value) if (_set_->count == 0) _set_->root = ((void *)0); _set_->count--; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->delete) _set_->callbacks->delete (); return 1; @@ -371,7 +371,7 @@ _Bool ts_max(struct treeset *_set_, size_t *value) { if (ts_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *scan = _set_->root; @@ -379,7 +379,7 @@ _Bool ts_max(struct treeset *_set_, size_t *value) scan = scan->right; if (value) *value = scan->value; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); return 1; @@ -388,7 +388,7 @@ _Bool ts_min(struct treeset *_set_, size_t *value) { if (ts_empty(_set_)) { - _set_->flag = cmc_flags.EMPTY; + _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *scan = _set_->root; @@ -396,7 +396,7 @@ _Bool ts_min(struct treeset *_set_, size_t *value) scan = scan->left; if (value) *value = scan->value; - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; if (_set_->callbacks && _set_->callbacks->read) _set_->callbacks->read(); return 1; @@ -426,7 +426,7 @@ struct treeset *ts_copy_of(struct treeset *_set_) ts_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks); if (!result) { - _set_->flag = cmc_flags.ERROR; + _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } if (!ts_empty(_set_)) @@ -440,13 +440,13 @@ struct treeset *ts_copy_of(struct treeset *_set_) ts_insert(result, ts_iter_value(&iter)); } } - _set_->flag = cmc_flags.OK; + _set_->flag = CMC_FLAG_OK; return result; } _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) { - _set1_->flag = cmc_flags.OK; - _set2_->flag = cmc_flags.OK; + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; struct treeset_iter iter = ts_iter_start(_set1_); @@ -461,9 +461,10 @@ struct cmc_string ts_to_string(struct treeset *_set_) { struct cmc_string str; struct treeset *s_ = _set_; - int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_treeset, "treeset", - "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, - s_->alloc, s_->callbacks); + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treeset, + "CMC_PARAM_SNAME((ts, treeset, , , size_t))", + "CMC_PARAM_V((ts, treeset, , , size_t))", s_, s_->root, + s_->count, s_->flag, s_->f_val, s_->alloc, s_->callbacks); return n >= 0 ? str : (struct cmc_string){ 0 }; } _Bool ts_print(struct treeset *_set_, FILE *fptr) diff --git a/tests/main/unt/bitset.c b/tests/main/unt/bitset.c index 85c61b9..7c39da6 100644 --- a/tests/main/unt/bitset.c +++ b/tests/main/unt/bitset.c @@ -106,19 +106,19 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_not_equals(ptr, NULL, bs); - bs->flag = cmc_flags.ERROR; + bs->flag = CMC_FLAG_ERROR; bs_customize(bs, bs_alloc_node, callbacks); cmc_assert_equals(ptr, bs_alloc_node, bs->alloc); cmc_assert_equals(ptr, callbacks, bs->callbacks); - cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); - bs->flag = cmc_flags.ERROR; + bs->flag = CMC_FLAG_ERROR; bs_customize(bs, NULL, NULL); cmc_assert_equals(ptr, &cmc_alloc_node_default, bs->alloc); cmc_assert_equals(ptr, NULL, bs->callbacks); - cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); bs_free(bs); }); @@ -129,10 +129,10 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_not_equals(ptr, NULL, bs); cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - bs->flag = cmc_flags.ERROR; + bs->flag = CMC_FLAG_ERROR; cmc_assert(bs_set(bs, 0)); cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]); - cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); bs->buffer[0] = 0; @@ -160,13 +160,13 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_not_equals(ptr, NULL, bs); cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - bs->flag = cmc_flags.ERROR; + bs->flag = CMC_FLAG_ERROR; cmc_assert(bs_set_range(bs, 0, 0)); cmc_assert_equals(uint8_t, 1, bs->buffer[0]); - cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); cmc_assert(!bs_set_range(bs, 1, 0)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, bs->flag); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, bs->flag); bs->buffer[0] = 0; @@ -231,7 +231,7 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); cmc_assert(!bs_clear_range(bs, 1, 0)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, bs->flag); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, bs->flag); cmc_assert(bs_clear_range(bs, 0, word_bits * 100 - 1)); cmc_assert_equals(size_t, 100, bs->capacity); diff --git a/tests/main/unt/deque.c b/tests/main/unt/deque.c index c46374d..5706294 100644 --- a/tests/main/unt/deque.c +++ b/tests/main/unt/deque.c @@ -32,7 +32,7 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(size_t, 0, d->count); cmc_assert_equals(size_t, 0, d->front); cmc_assert_equals(size_t, 0, d->back); - cmc_assert_equals(int32_t, cmc_flags.OK, d->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag); cmc_assert_equals(ptr, d_fval, d->f_val); cmc_assert_equals(ptr, &cmc_alloc_node_default, d->alloc); cmc_assert_equals(ptr, NULL, d->callbacks); @@ -59,7 +59,7 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(size_t, 0, d->count); cmc_assert_equals(size_t, 0, d->front); cmc_assert_equals(size_t, 0, d->back); - cmc_assert_equals(int32_t, cmc_flags.OK, d->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag); cmc_assert_equals(ptr, d_fval, d->f_val); cmc_assert_equals(ptr, d_alloc_node, d->alloc); cmc_assert_equals(ptr, callbacks, d->callbacks); @@ -76,74 +76,74 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(ptr, NULL, d); }); - CMC_CREATE_TEST(PFX##_init(), { - struct deque d = d_init(1000000, d_fval); + // CMC_CREATE_TEST(PFX##_init(), { + // struct deque d = d_init(1000000, d_fval); - cmc_assert_not_equals(ptr, NULL, d.buffer); - cmc_assert_equals(size_t, 1000000, d.capacity); - cmc_assert_equals(size_t, 0, d.count); - cmc_assert_equals(size_t, 0, d.front); - cmc_assert_equals(size_t, 0, d.back); - cmc_assert_equals(int32_t, cmc_flags.OK, d.flag); - cmc_assert_equals(ptr, d_fval, d.f_val); - cmc_assert_equals(ptr, &cmc_alloc_node_default, d.alloc); - cmc_assert_equals(ptr, NULL, d.callbacks); + // cmc_assert_not_equals(ptr, NULL, d.buffer); + // cmc_assert_equals(size_t, 1000000, d.capacity); + // cmc_assert_equals(size_t, 0, d.count); + // cmc_assert_equals(size_t, 0, d.front); + // cmc_assert_equals(size_t, 0, d.back); + // cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); + // cmc_assert_equals(ptr, d_fval, d.f_val); + // cmc_assert_equals(ptr, &cmc_alloc_node_default, d.alloc); + // cmc_assert_equals(ptr, NULL, d.callbacks); - d_release(d); + // d_release(d); - d = d_init(0, d_fval); + // d = d_init(0, d_fval); - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); + // cmc_assert_equals(size_t, 0, d.capacity); + // cmc_assert_equals(ptr, NULL, d.buffer); - d = d_init(1000, NULL); + // d = d_init(1000, NULL); - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); + // cmc_assert_equals(size_t, 0, d.capacity); + // cmc_assert_equals(ptr, NULL, d.buffer); - d = d_init(UINT64_MAX, d_fval); + // d = d_init(UINT64_MAX, d_fval); - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); + // cmc_assert_equals(size_t, 0, d.capacity); + // cmc_assert_equals(ptr, NULL, d.buffer); - if (d.buffer) - d_release(d); - }); + // if (d.buffer) + // d_release(d); + // }); - CMC_CREATE_TEST(PFX##_init_custom(), { - struct deque d = - d_init_custom(1000000, d_fval, d_alloc_node, callbacks); + // CMC_CREATE_TEST(PFX##_init_custom(), { + // struct deque d = + // d_init_custom(1000000, d_fval, d_alloc_node, callbacks); - cmc_assert_not_equals(ptr, NULL, d.buffer); - cmc_assert_equals(size_t, 1000000, d.capacity); - cmc_assert_equals(size_t, 0, d.count); - cmc_assert_equals(size_t, 0, d.front); - cmc_assert_equals(size_t, 0, d.back); - cmc_assert_equals(int32_t, cmc_flags.OK, d.flag); - cmc_assert_equals(ptr, d_fval, d.f_val); - cmc_assert_equals(ptr, d_alloc_node, d.alloc); - cmc_assert_equals(ptr, callbacks, d.callbacks); + // cmc_assert_not_equals(ptr, NULL, d.buffer); + // cmc_assert_equals(size_t, 1000000, d.capacity); + // cmc_assert_equals(size_t, 0, d.count); + // cmc_assert_equals(size_t, 0, d.front); + // cmc_assert_equals(size_t, 0, d.back); + // cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); + // cmc_assert_equals(ptr, d_fval, d.f_val); + // cmc_assert_equals(ptr, d_alloc_node, d.alloc); + // cmc_assert_equals(ptr, callbacks, d.callbacks); - d_release(d); + // d_release(d); - d = d_init_custom(0, d_fval, d_alloc_node, callbacks); + // d = d_init_custom(0, d_fval, d_alloc_node, callbacks); - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); + // cmc_assert_equals(size_t, 0, d.capacity); + // cmc_assert_equals(ptr, NULL, d.buffer); - d = d_init_custom(1000, NULL, d_alloc_node, callbacks); + // d = d_init_custom(1000, NULL, d_alloc_node, callbacks); - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); + // cmc_assert_equals(size_t, 0, d.capacity); + // cmc_assert_equals(ptr, NULL, d.buffer); - d = d_init_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); + // d = d_init_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); + // cmc_assert_equals(size_t, 0, d.capacity); + // cmc_assert_equals(ptr, NULL, d.buffer); - if (d.buffer) - d_release(d); - }); + // if (d.buffer) + // d_release(d); + // }); CMC_CREATE_TEST(PFX##_clear(), { v_total_free = 0; @@ -156,11 +156,11 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(size_t, 50, d_count(d)); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; d_clear(d); cmc_assert_equals(size_t, 50, v_total_free); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); cmc_assert_equals(size_t, 0, d_count(d)); cmc_assert_equals(size_t, 100, d_capacity(d)); @@ -182,11 +182,11 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(size_t, 500500, sum); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; d_clear(d); cmc_assert_equals(size_t, 1050, v_total_free); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); sum = 0; for (size_t i = 0; i < d->capacity; i++) @@ -232,55 +232,55 @@ CMC_CREATE_UNIT(Deque, true, { v_total_free = 0; }); - CMC_CREATE_TEST(PFX##_release(), { - v_total_free = 0; + // CMC_CREATE_TEST(PFX##_release(), { + // v_total_free = 0; - struct deque d = d_init(100, d_fval_counter); + // struct deque d = d_init(100, d_fval_counter); - cmc_assert_not_equals(ptr, NULL, d.buffer); + // cmc_assert_not_equals(ptr, NULL, d.buffer); - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - d_push_front(&d, i); - else - d_push_back(&d, i); - } + // for (size_t i = 1; i <= 1000; i++) + // { + // if (i % 2 == 0) + // d_push_front(&d, i); + // else + // d_push_back(&d, i); + // } - cmc_assert_equals(size_t, 1000, d_count(&d)); + // cmc_assert_equals(size_t, 1000, d_count(&d)); - size_t sum = 0; - for (size_t i = d.front, j = 0; j < d.count; - i = (i + 1) % d.capacity, j++) - sum += d.buffer[i]; + // size_t sum = 0; + // for (size_t i = d.front, j = 0; j < d.count; + // i = (i + 1) % d.capacity, j++) + // sum += d.buffer[i]; - cmc_assert_equals(size_t, 500500, sum); + // cmc_assert_equals(size_t, 500500, sum); - d_release(d); + // d_release(d); - cmc_assert_equals(size_t, 1000, v_total_free); + // cmc_assert_equals(size_t, 1000, v_total_free); - v_total_free = 0; - }); + // v_total_free = 0; + // }); CMC_CREATE_TEST(PFX##_customize(), { struct deque *d = d_new(100, d_fval); cmc_assert_not_equals(ptr, NULL, d); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; d_customize(d, d_alloc_node, callbacks); cmc_assert_equals(ptr, d_alloc_node, d->alloc); cmc_assert_equals(ptr, callbacks, d->callbacks); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; d_customize(d, NULL, NULL); cmc_assert_equals(ptr, &cmc_alloc_node_default, d->alloc); cmc_assert_equals(ptr, NULL, d->callbacks); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); d_free(d); }); @@ -291,12 +291,12 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_not_equals(ptr, NULL, d); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_push_front(d, 10)); cmc_assert_equals(size_t, 1, d_count(d)); cmc_assert_equals(int32_t, 1, total_create); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); d_customize(d, NULL, NULL); @@ -339,12 +339,12 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_not_equals(ptr, NULL, d); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_push_front(d, 10)); cmc_assert_equals(size_t, 1, d_count(d)); cmc_assert_equals(int32_t, 1, total_create); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); d_customize(d, NULL, NULL); @@ -387,14 +387,14 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_not_equals(ptr, NULL, d); cmc_assert(!d_pop_front(d)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); cmc_assert(d_push_front(d, 10)); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_pop_front(d)); cmc_assert_equals(size_t, 0, d_count(d)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); cmc_assert(d_push_back(d, 10)); cmc_assert(d_pop_front(d)); @@ -454,14 +454,14 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_not_equals(ptr, NULL, d); cmc_assert(!d_pop_back(d)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); cmc_assert(d_push_front(d, 10)); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_pop_back(d)); cmc_assert_equals(size_t, 0, d_count(d)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); cmc_assert(d_push_back(d, 10)); cmc_assert(d_pop_back(d)); @@ -520,13 +520,13 @@ CMC_CREATE_UNIT(Deque, true, { d_front(d); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); cmc_assert(d_push_front(d, 99)); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 99, d_front(d)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); cmc_assert(d_push_back(d, 98)); cmc_assert_equals(size_t, 99, d_front(d)); @@ -573,13 +573,13 @@ CMC_CREATE_UNIT(Deque, true, { d_back(d); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); cmc_assert(d_push_back(d, 99)); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 99, d_back(d)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); cmc_assert(d_push_front(d, 98)); cmc_assert_equals(size_t, 99, d_back(d)); @@ -754,7 +754,7 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_not_equals(ptr, NULL, d); cmc_assert_equals(size_t, 100, d_capacity(d)); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_resize(d, 100)); cmc_assert_equals(size_t, 100, d_capacity(d)); @@ -781,7 +781,7 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(size_t, 150, d_capacity(d)); cmc_assert(!d_resize(d, d_count(d) - 10)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, d_flag(d)); d_free(d); @@ -1107,82 +1107,82 @@ CMC_CREATE_UNIT(Deque, true, { struct deque *d = d_new(100, d_fval); cmc_assert_not_equals(ptr, NULL, d); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); // customize - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; d_customize(d, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 }); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); // push_front - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_push_front(d, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); // pop_front - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_pop_front(d)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); cmc_assert(!d_pop_front(d)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); // push_back cmc_assert(d_push_back(d, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); // pop_back - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_pop_back(d)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); cmc_assert(!d_pop_back(d)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); // front - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_front(d) == 0); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); cmc_assert(d_push_back(d, 1)); - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_front(d) == 1); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); // clear - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; d_clear(d); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); // back cmc_assert(d_back(d) == 0); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); cmc_assert(d_push_front(d, 1)); cmc_assert(d_back(d) == 1); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); // contains - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; cmc_assert(d_contains(d, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); // copy_of - d->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; struct deque *d2 = d_copy_of(d); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d2)); // equals cmc_assert(d_pop_back(d)); cmc_assert(d_pop_back(d2)); - d->flag = cmc_flags.ERROR; - d2->flag = cmc_flags.ERROR; + d->flag = CMC_FLAG_ERROR; + d2->flag = CMC_FLAG_ERROR; d_front(d); d_front(d2); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d2)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d2)); cmc_assert(d_equals(d, d2)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d)); - cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d2)); d_free(d); d_free(d2); diff --git a/tests/main/unt/hashbidimap.c b/tests/main/unt/hashbidimap.c index d9342a1..40f139f 100644 --- a/tests/main/unt/hashbidimap.c +++ b/tests/main/unt/hashbidimap.c @@ -48,7 +48,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert_not_equals(ptr, NULL, map->buffer); cmc_assert_equals(size_t, 0, map->count); cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hbm_fkey, map->f_key); cmc_assert_equals(ptr, hbm_fval, map->f_val); cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); @@ -94,7 +94,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert_not_equals(ptr, NULL, map->buffer); cmc_assert_equals(size_t, 0, map->count); cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hbm_fkey, map->f_key); cmc_assert_equals(ptr, hbm_fval, map->f_val); cmc_assert_equals(ptr, hbm_alloc_node, map->alloc); @@ -133,11 +133,11 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert_equals(size_t, 1000, map->count); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; hbm_clear(map); cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(int32_t, 1000, k_total_free); cmc_assert_equals(int32_t, 1000, v_total_free); @@ -365,7 +365,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert(!hbm_update_key(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); hbm_free(map); }); @@ -379,21 +379,21 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert_equals(size_t, 1, hbm_count(map)); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(hbm_update_key(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); cmc_assert(!hbm_update_key(map, 2, 2)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); cmc_assert(hbm_insert(map, 2, 2)); cmc_assert(!hbm_update_key(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); cmc_assert(!hbm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); cmc_assert(hbm_update_key(map, 2, 2)); @@ -432,7 +432,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert(!hbm_update_val(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); hbm_free(map); }); @@ -446,21 +446,21 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert_equals(size_t, 1, hbm_count(map)); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(hbm_update_val(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); cmc_assert(!hbm_update_val(map, 2, 2)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); cmc_assert(hbm_insert(map, 2, 2)); cmc_assert(!hbm_update_val(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); cmc_assert(!hbm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); cmc_assert(hbm_update_val(map, 2, 2)); @@ -598,133 +598,133 @@ CMC_CREATE_UNIT(HashBidiMap, true, { struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); // customize hbm_customize(map, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 }); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); // Insert cmc_assert(hbm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); cmc_assert(!hbm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); + map->flag = CMC_FLAG_ERROR; cmc_assert(!hbm_insert(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); // clear hbm_clear(map); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); // hbm_update_key cmc_assert(!hbm_update_key(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); cmc_assert(hbm_insert(map, 1, 1)); cmc_assert(!hbm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); cmc_assert(hbm_insert(map, 2, 2)); cmc_assert(!hbm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); + map->flag = CMC_FLAG_ERROR; cmc_assert(!hbm_update_key(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); // clear hbm_clear(map); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); // hbm_update_val cmc_assert(!hbm_update_val(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); cmc_assert(hbm_insert(map, 1, 1)); cmc_assert(!hbm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); cmc_assert(hbm_insert(map, 2, 2)); cmc_assert(!hbm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); + map->flag = CMC_FLAG_ERROR; cmc_assert(!hbm_update_val(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); // remove_by_key cmc_assert(hbm_remove_by_key(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); cmc_assert(!hbm_remove_by_key(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); cmc_assert(hbm_remove_by_key(map, 2, NULL, NULL)); cmc_assert(!hbm_remove_by_key(map, 2, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); // remove_by_val cmc_assert(hbm_insert(map, 1, 1) && hbm_insert(map, 2, 2)); cmc_assert(hbm_remove_by_val(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); cmc_assert(!hbm_remove_by_val(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); cmc_assert(hbm_remove_by_val(map, 2, NULL, NULL)); cmc_assert(!hbm_remove_by_val(map, 2, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); // get_key and get_val cmc_assert(hbm_insert(map, 2, 1)); cmc_assert_equals(size_t, 2, hbm_get_key(map, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); + map->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 1, hbm_get_val(map, 2)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); cmc_assert_equals(size_t, 0, hbm_get_key(map, 2)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); + map->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 0, hbm_get_val(map, 1)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); // contains_key cmc_assert(hbm_contains_key(map, 2)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); // contains_val - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(hbm_contains_val(map, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); // copy_of - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; struct hashbidimap *map2 = hbm_copy_of(map); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map2)); size_t tmp = map->capacity; map->capacity = 0; struct hashbidimap *map3 = hbm_copy_of(map); cmc_assert_equals(ptr, NULL, map3); - cmc_assert_equals(int32_t, cmc_flags.ERROR, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hbm_flag(map)); map->capacity = tmp; // equals hbm_get_key(map, 100); hbm_get_key(map2, 100); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map2)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map2)); + map->flag = CMC_FLAG_ERROR; cmc_assert(hbm_equals(map, map2)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map2)); hbm_free(map); hbm_free(map2); diff --git a/tests/main/unt/hashmap.c b/tests/main/unt/hashmap.c index f43e576..e2406a5 100644 --- a/tests/main/unt/hashmap.c +++ b/tests/main/unt/hashmap.c @@ -44,7 +44,7 @@ CMC_CREATE_UNIT(HashMap, true, { cmc_assert_not_equals(ptr, NULL, map->buffer); cmc_assert_equals(size_t, 0, map->count); cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hm_fkey, map->f_key); cmc_assert_equals(ptr, hm_fval, map->f_val); cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); @@ -78,7 +78,7 @@ CMC_CREATE_UNIT(HashMap, true, { cmc_assert_not_equals(ptr, NULL, map->buffer); cmc_assert_equals(size_t, 0, map->count); cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hm_fkey, map->f_key); cmc_assert_equals(ptr, hm_fval, map->f_val); cmc_assert_equals(ptr, hm_alloc_node, map->alloc); @@ -104,70 +104,70 @@ CMC_CREATE_UNIT(HashMap, true, { cmc_assert_equals(ptr, NULL, map); }); - CMC_CREATE_TEST(PFX##_init(), { - struct hashmap map = hm_init(943722, 0.6, hm_fkey, hm_fval); + // CMC_CREATE_TEST(PFX##_init(), { + // struct hashmap map = hm_init(943722, 0.6, hm_fkey, hm_fval); - cmc_assert_not_equals(ptr, NULL, map.buffer); - cmc_assert_equals(size_t, 0, map.count); - cmc_assert_equals(double, 0.6, map.load); - cmc_assert_equals(int32_t, cmc_flags.OK, map.flag); - cmc_assert_equals(ptr, hm_fkey, map.f_key); - cmc_assert_equals(ptr, hm_fval, map.f_val); - cmc_assert_equals(ptr, &cmc_alloc_node_default, map.alloc); - cmc_assert_equals(ptr, NULL, map.callbacks); + // cmc_assert_not_equals(ptr, NULL, map.buffer); + // cmc_assert_equals(size_t, 0, map.count); + // cmc_assert_equals(double, 0.6, map.load); + // cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag); + // cmc_assert_equals(ptr, hm_fkey, map.f_key); + // cmc_assert_equals(ptr, hm_fval, map.f_val); + // cmc_assert_equals(ptr, &cmc_alloc_node_default, map.alloc); + // cmc_assert_equals(ptr, NULL, map.callbacks); - cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); + // cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); - hm_release(map); + // hm_release(map); - map = hm_init(0, 0.6, hm_fkey, hm_fval); - cmc_assert_equals(ptr, NULL, map.buffer); + // map = hm_init(0, 0.6, hm_fkey, hm_fval); + // cmc_assert_equals(ptr, NULL, map.buffer); - map = hm_init(UINT64_MAX, 0.99, hm_fkey, hm_fval); - cmc_assert_equals(ptr, NULL, map.buffer); + // map = hm_init(UINT64_MAX, 0.99, hm_fkey, hm_fval); + // cmc_assert_equals(ptr, NULL, map.buffer); - map = hm_init(1000, 0.6, hm_fkey, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); + // map = hm_init(1000, 0.6, hm_fkey, NULL); + // cmc_assert_equals(ptr, NULL, map.buffer); - map = hm_init(1000, 0.6, NULL, hm_fval); - cmc_assert_equals(ptr, NULL, map.buffer); + // map = hm_init(1000, 0.6, NULL, hm_fval); + // cmc_assert_equals(ptr, NULL, map.buffer); - map = hm_init(1000, 0.6, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - }); + // map = hm_init(1000, 0.6, NULL, NULL); + // cmc_assert_equals(ptr, NULL, map.buffer); + // }); - CMC_CREATE_TEST(PFX##_init_custom(), { - struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, - hm_alloc_node, callbacks); + // CMC_CREATE_TEST(PFX##_init_custom(), { + // struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, + // hm_alloc_node, callbacks); - cmc_assert_not_equals(ptr, NULL, map.buffer); - cmc_assert_equals(size_t, 0, map.count); - cmc_assert_equals(double, 0.6, map.load); - cmc_assert_equals(int32_t, cmc_flags.OK, map.flag); - cmc_assert_equals(ptr, hm_fkey, map.f_key); - cmc_assert_equals(ptr, hm_fval, map.f_val); - cmc_assert_equals(ptr, hm_alloc_node, map.alloc); - cmc_assert_equals(ptr, callbacks, map.callbacks); + // cmc_assert_not_equals(ptr, NULL, map.buffer); + // cmc_assert_equals(size_t, 0, map.count); + // cmc_assert_equals(double, 0.6, map.load); + // cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag); + // cmc_assert_equals(ptr, hm_fkey, map.f_key); + // cmc_assert_equals(ptr, hm_fval, map.f_val); + // cmc_assert_equals(ptr, hm_alloc_node, map.alloc); + // cmc_assert_equals(ptr, callbacks, map.callbacks); - cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); + // cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); - hm_release(map); + // hm_release(map); - map = hm_init_custom(0, 0.6, hm_fkey, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); + // map = hm_init_custom(0, 0.6, hm_fkey, hm_fval, NULL, NULL); + // cmc_assert_equals(ptr, NULL, map.buffer); - map = hm_init_custom(UINT64_MAX, 0.99, hm_fkey, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); + // map = hm_init_custom(UINT64_MAX, 0.99, hm_fkey, hm_fval, NULL, NULL); + // cmc_assert_equals(ptr, NULL, map.buffer); - map = hm_init_custom(1000, 0.6, hm_fkey, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); + // map = hm_init_custom(1000, 0.6, hm_fkey, NULL, NULL, NULL); + // cmc_assert_equals(ptr, NULL, map.buffer); - map = hm_init_custom(1000, 0.6, NULL, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); + // map = hm_init_custom(1000, 0.6, NULL, hm_fval, NULL, NULL); + // cmc_assert_equals(ptr, NULL, map.buffer); - map = hm_init_custom(1000, 0.6, NULL, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - }); + // map = hm_init_custom(1000, 0.6, NULL, NULL, NULL, NULL); + // cmc_assert_equals(ptr, NULL, map.buffer); + // }); CMC_CREATE_TEST(PFX##_clear(), { k_total_free = 0; @@ -186,11 +186,11 @@ CMC_CREATE_UNIT(HashMap, true, { cmc_assert_equals(size_t, 100, *r); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; hm_clear(map); cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(int32_t, 1000, k_total_free); cmc_assert_equals(int32_t, 1000, v_total_free); @@ -233,54 +233,54 @@ CMC_CREATE_UNIT(HashMap, true, { v_total_free = 0; }); - CMC_CREATE_TEST(PFX##_release(), { - k_total_free = 0; - v_total_free = 0; - struct hashmap map = - hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter); + // CMC_CREATE_TEST(PFX##_release(), { + // k_total_free = 0; + // v_total_free = 0; + // struct hashmap map = + // hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter); - cmc_assert_not_equals(ptr, NULL, map.buffer); + // cmc_assert_not_equals(ptr, NULL, map.buffer); - for (size_t i = 1; i <= 1000; i++) - hm_insert(&map, i, i); + // for (size_t i = 1; i <= 1000; i++) + // hm_insert(&map, i, i); - cmc_assert_equals(size_t, 1000, map.count); + // cmc_assert_equals(size_t, 1000, map.count); - hm_release(map); + // hm_release(map); - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); + // cmc_assert_equals(int32_t, 1000, k_total_free); + // cmc_assert_equals(int32_t, 1000, v_total_free); - map = hm_init(1000, 0.6, hm_fkey_counter, hm_fval_counter); + // map = hm_init(1000, 0.6, hm_fkey_counter, hm_fval_counter); - cmc_assert_not_equals(ptr, NULL, map.buffer); + // cmc_assert_not_equals(ptr, NULL, map.buffer); - hm_release(map); + // hm_release(map); - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - k_total_free = 0; - v_total_free = 0; - }); + // cmc_assert_equals(int32_t, 1000, k_total_free); + // cmc_assert_equals(int32_t, 1000, v_total_free); + // k_total_free = 0; + // v_total_free = 0; + // }); CMC_CREATE_TEST(PFX##_customize(), { struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); cmc_assert_not_equals(ptr, NULL, map); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; hm_customize(map, hm_alloc_node, callbacks); cmc_assert_equals(ptr, hm_alloc_node, map->alloc); cmc_assert_equals(ptr, callbacks, map->callbacks); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; hm_customize(map, NULL, NULL); cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); cmc_assert_equals(ptr, NULL, map->callbacks); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); hm_free(map); }); @@ -290,9 +290,9 @@ CMC_CREATE_UNIT(HashMap, true, { cmc_assert_not_equals(ptr, NULL, map); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(hm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(size_t, 1, hm_count(map)); hm_free(map); @@ -705,92 +705,92 @@ CMC_CREATE_UNIT(HashMap, true, { struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); // insert cmc_assert(hm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); cmc_assert(!hm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hm_flag(map)); // clear hm_clear(map); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); // update cmc_assert(!hm_update(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); cmc_assert(hm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); cmc_assert(!hm_update(map, 2, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map)); cmc_assert(hm_update(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); // remove cmc_assert(!hm_remove(map, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map)); cmc_assert(hm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); cmc_assert(!hm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); // max cmc_assert(hm_insert(map, 1, 1)); cmc_assert(hm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); cmc_assert(hm_remove(map, 1, NULL)); cmc_assert(!hm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); // min cmc_assert(hm_insert(map, 1, 1)); cmc_assert(hm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); cmc_assert(hm_remove(map, 1, NULL)); cmc_assert(!hm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); // get hm_get(map, 1); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); cmc_assert(hm_insert(map, 1, 1)); hm_get(map, 1); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); hm_get(map, 2); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map)); hm_clear(map); // get_ref hm_get_ref(map, 1); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); cmc_assert(hm_insert(map, 1, 1)); hm_get_ref(map, 1); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); hm_get_ref(map, 2); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map)); // contains hm_contains(map, 1); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); // copy struct hashmap *map2 = hm_copy_of(map); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map2)); size_t tmp = map->capacity; map->capacity = 0; @@ -798,13 +798,13 @@ CMC_CREATE_UNIT(HashMap, true, { struct hashmap *map3 = hm_copy_of(map); cmc_assert_equals(ptr, NULL, map3); - cmc_assert_equals(int32_t, cmc_flags.ERROR, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hm_flag(map)); map->capacity = tmp; cmc_assert(hm_equals(map, map2)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map2)); hm_free(map); hm_free(map2); diff --git a/tests/main/unt/hashmultimap.c b/tests/main/unt/hashmultimap.c index dfacb6a..647d804 100644 --- a/tests/main/unt/hashmultimap.c +++ b/tests/main/unt/hashmultimap.c @@ -48,7 +48,7 @@ CMC_CREATE_UNIT(HashMultiMap, true, { cmc_assert_not_equals(ptr, NULL, map->buffer); cmc_assert_equals(size_t, 0, map->count); cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hmm_fkey, map->f_key); cmc_assert_equals(ptr, hmm_fval, map->f_val); cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); @@ -94,7 +94,7 @@ CMC_CREATE_UNIT(HashMultiMap, true, { cmc_assert_not_equals(ptr, NULL, map->buffer); cmc_assert_equals(size_t, 0, map->count); cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hmm_fkey, map->f_key); cmc_assert_equals(ptr, hmm_fval, map->f_val); cmc_assert_equals(ptr, hmm_alloc_node, map->alloc); @@ -133,11 +133,11 @@ CMC_CREATE_UNIT(HashMultiMap, true, { cmc_assert_equals(size_t, 1000, map->count); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; hmm_clear(map); cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(int32_t, cmc_flags.OK, map->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(int32_t, 1000, k_total_free); cmc_assert_equals(int32_t, 1000, v_total_free); @@ -263,117 +263,117 @@ CMC_CREATE_UNIT(HashMultiMap, true, { struct hashmultimap *map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // clear - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; hmm_clear(map); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // customize - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; hmm_customize(map, NULL, NULL); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // insert - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // update cmc_assert(!hmm_update(map, 9, 10, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); cmc_assert(hmm_update(map, 1, 20, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // update_all - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 1, hmm_update_all(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 0, hmm_update_all(map, 2, 4, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); hmm_clear(map); cmc_assert_equals(size_t, 0, hmm_update_all(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); // remove - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(!hmm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); cmc_assert(hmm_insert(map, 1, 1)); cmc_assert(!hmm_remove(map, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); cmc_assert(hmm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // remove_all cmc_assert(!hmm_remove_all(map, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); cmc_assert(hmm_insert(map, 1, 1) && hmm_insert(map, 1, 1)); cmc_assert_equals(size_t, 0, hmm_remove_all(map, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); cmc_assert_equals(size_t, 2, hmm_remove_all(map, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // max min cmc_assert(!hmm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); + map->flag = CMC_FLAG_ERROR; cmc_assert(!hmm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); cmc_assert(hmm_insert(map, 1, 1)); cmc_assert(hmm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); + map->flag = CMC_FLAG_ERROR; cmc_assert(hmm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // get get_ref hmm_get(map, 2); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); + map->flag = CMC_FLAG_ERROR; hmm_get_ref(map, 2); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); hmm_get(map, 1); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); + map->flag = CMC_FLAG_ERROR; hmm_get_ref(map, 1); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); hmm_clear(map); hmm_get(map, 1); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map)); - map->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); + map->flag = CMC_FLAG_ERROR; hmm_get_ref(map, 1); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); // contains - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(!hmm_contains(map, 1000)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); // copy_of - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; struct hashmultimap *map2 = hmm_copy_of(map); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map2)); // equals - map->flag = cmc_flags.ERROR; - map2->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; + map2->flag = CMC_FLAG_ERROR; cmc_assert(hmm_equals(map, map2)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map2)); hmm_free(map); hmm_free(map2); diff --git a/tests/main/unt/hashmultiset.c b/tests/main/unt/hashmultiset.c index 2c2bf74..cccb6d8 100644 --- a/tests/main/unt/hashmultiset.c +++ b/tests/main/unt/hashmultiset.c @@ -32,7 +32,7 @@ CMC_CREATE_UNIT(HashMultiSet, true, { cmc_assert_not_equals(ptr, NULL, set->buffer); cmc_assert_equals(size_t, 0, set->count); cmc_assert_equals(double, 0.6, set->load); - cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); cmc_assert_equals(ptr, hms_fval, set->f_val); cmc_assert_equals(ptr, &cmc_alloc_node_default, set->alloc); cmc_assert_equals(ptr, NULL, set->callbacks); @@ -62,7 +62,7 @@ CMC_CREATE_UNIT(HashMultiSet, true, { cmc_assert_not_equals(ptr, NULL, set->buffer); cmc_assert_equals(size_t, 0, set->count); cmc_assert_equals(double, 0.6, set->load); - cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); cmc_assert_equals(ptr, hms_fval, set->f_val); cmc_assert_equals(ptr, hms_alloc_node, set->alloc); cmc_assert_equals(ptr, callbacks, set->callbacks); @@ -92,11 +92,11 @@ CMC_CREATE_UNIT(HashMultiSet, true, { cmc_assert_equals(size_t, 1000, set->count); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; hms_clear(set); cmc_assert_equals(size_t, 0, set->count); - cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); cmc_assert_equals(int32_t, 1000, v_total_free); hms_free(set); @@ -236,100 +236,100 @@ CMC_CREATE_UNIT(HashMultiSet, true, { struct hashmultiset *set = hms_new(100, 0.6, hms_fval); cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // clear - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; hms_clear(set); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // customize - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; hms_customize(set, NULL, NULL); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // insert - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(hms_insert(set, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(hms_insert(set, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // insert_many - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(hms_insert_many(set, 1, 0)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(hms_insert_many(set, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // update - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(hms_update(set, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(hms_update(set, 10, 0)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // remove cmc_assert(!hms_remove(set, 10)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hms_flag(set)); cmc_assert(hms_remove(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // remove_all cmc_assert_equals(size_t, 0, hms_remove_all(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set)); cmc_assert(hms_insert_many(set, 1, 10)); cmc_assert_equals(size_t, 0, hms_remove_all(set, 10)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hms_flag(set)); cmc_assert_equals(size_t, 10, hms_remove_all(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // max min cmc_assert(!hms_max(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hms_flag(set)); - set->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set)); + set->flag = CMC_FLAG_ERROR; cmc_assert(!hms_min(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set)); cmc_assert(hms_insert(set, 1)); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(hms_max(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); - set->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); + set->flag = CMC_FLAG_ERROR; cmc_assert(hms_min(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // multiplicity_of - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 0, hms_multiplicity_of(set, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // contains - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(!hms_contains(set, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); // copy_of - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; struct hashmultiset *set2 = hms_copy_of(set); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set2)); // equals - set->flag = cmc_flags.ERROR; - set2->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; + set2->flag = CMC_FLAG_ERROR; cmc_assert(hms_equals(set, set2)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set)); - cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set2)); hms_free(set); hms_free(set2); diff --git a/tests/main/unt/hashset.c b/tests/main/unt/hashset.c index 22bdd0e..df242d3 100644 --- a/tests/main/unt/hashset.c +++ b/tests/main/unt/hashset.c @@ -30,7 +30,7 @@ CMC_CREATE_UNIT(HashSet, true, { cmc_assert_not_equals(ptr, NULL, set->buffer); cmc_assert_equals(size_t, 0, set->count); cmc_assert_equals(double, 0.6, set->load); - cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); cmc_assert_equals(ptr, hs_fval, set->f_val); cmc_assert_equals(ptr, &cmc_alloc_node_default, set->alloc); cmc_assert_equals(ptr, NULL, set->callbacks); @@ -60,7 +60,7 @@ CMC_CREATE_UNIT(HashSet, true, { cmc_assert_not_equals(ptr, NULL, set->buffer); cmc_assert_equals(size_t, 0, set->count); cmc_assert_equals(double, 0.6, set->load); - cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); cmc_assert_equals(ptr, hs_fval, set->f_val); cmc_assert_equals(ptr, hs_alloc_node, set->alloc); cmc_assert_equals(ptr, callbacks, set->callbacks); @@ -90,11 +90,11 @@ CMC_CREATE_UNIT(HashSet, true, { cmc_assert_equals(size_t, 1000, set->count); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; hs_clear(set); cmc_assert_equals(size_t, 0, set->count); - cmc_assert_equals(int32_t, cmc_flags.OK, set->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); cmc_assert_equals(int32_t, 1000, v_total_free); hs_free(set); @@ -481,58 +481,58 @@ CMC_CREATE_UNIT(HashSet, true, { struct hashset *set = hs_new(1, 0.99, hs_fval); cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); // insert cmc_assert(hs_insert(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); cmc_assert(!hs_insert(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hs_flag(set)); // clear hs_clear(set); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); cmc_assert(hs_insert(set, 1)); // remove cmc_assert(!hs_remove(set, 2)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hs_flag(set)); cmc_assert(hs_remove(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); cmc_assert(!hs_remove(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set)); // max cmc_assert(hs_insert(set, 1)); cmc_assert(hs_max(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); cmc_assert(hs_remove(set, 1)); cmc_assert(!hs_max(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set)); // min cmc_assert(hs_insert(set, 1)); cmc_assert(hs_min(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); cmc_assert(hs_remove(set, 1)); cmc_assert(!hs_min(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set)); // contains hs_contains(set, 1); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); // copy - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; struct hashset *set2 = hs_copy_of(set); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set2)); size_t tmp = set->capacity; set->capacity = 0; @@ -540,13 +540,13 @@ CMC_CREATE_UNIT(HashSet, true, { struct hashset *set3 = hs_copy_of(set); cmc_assert_equals(ptr, NULL, set3); - cmc_assert_equals(int32_t, cmc_flags.ERROR, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hs_flag(set)); set->capacity = tmp; cmc_assert(hs_equals(set, set2)); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set)); - cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set2)); hs_free(set); hs_free(set2); diff --git a/tests/main/unt/heap.c b/tests/main/unt/heap.c index 2a3fe60..5dbaaa7 100644 --- a/tests/main/unt/heap.c +++ b/tests/main/unt/heap.c @@ -167,55 +167,55 @@ CMC_CREATE_UNIT(Heap, true, { struct heap *h = h_new(100, cmc_max_heap, h_fval); cmc_assert_not_equals(ptr, NULL, h); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - h->flag = cmc_flags.ERROR; + h->flag = CMC_FLAG_ERROR; // insert cmc_assert(h_insert(h, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - h->flag = cmc_flags.ERROR; + h->flag = CMC_FLAG_ERROR; // remove cmc_assert(h_remove(h)); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); cmc_assert(!h_remove(h)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, h_flag(h)); // peek cmc_assert(h_insert(h, 10)); h_peek(h); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); cmc_assert(h_remove(h)); h_peek(h); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, h_flag(h)); // clear h_clear(h); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - h->flag = cmc_flags.ERROR; + h->flag = CMC_FLAG_ERROR; // contains h_contains(h, 10); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - h->flag = cmc_flags.ERROR; + h->flag = CMC_FLAG_ERROR; // copy of struct heap *h2 = h_copy_of(h); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h2)); - h->flag = cmc_flags.ERROR; - h2->flag = cmc_flags.ERROR; + h->flag = CMC_FLAG_ERROR; + h2->flag = CMC_FLAG_ERROR; // equals cmc_assert(h_equals(h, h2)); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h)); - cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h2)); h_free(h); h_free(h2); diff --git a/tests/main/unt/intervalheap.c b/tests/main/unt/intervalheap.c index 88dea15..3a1e9b0 100644 --- a/tests/main/unt/intervalheap.c +++ b/tests/main/unt/intervalheap.c @@ -196,19 +196,19 @@ CMC_CREATE_UNIT(IntervalHeap, true, { CMC_CREATE_TEST(PFX##_customize(), { struct intervalheap *ih = ih_new(100, ih_fval); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; ih_customize(ih, ih_alloc_node, callbacks); cmc_assert_equals(ptr, ih_alloc_node, ih->alloc); cmc_assert_equals(ptr, callbacks, ih->callbacks); - cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; ih_customize(ih, NULL, NULL); cmc_assert_equals(ptr, &cmc_alloc_node_default, ih->alloc); cmc_assert_equals(ptr, NULL, ih->callbacks); - cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); ih_free(ih); }); @@ -299,15 +299,15 @@ CMC_CREATE_UNIT(IntervalHeap, true, { // count == 0 cmc_assert(!ih_remove_max(ih)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih->flag); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih->flag); // count == 1 cmc_assert(ih_insert(ih, 10)); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert(ih_remove_max(ih)); cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); for (size_t i = 1; i <= 1000; i++) ih_insert(ih, i); @@ -347,15 +347,15 @@ CMC_CREATE_UNIT(IntervalHeap, true, { // count == 0 cmc_assert(!ih_remove_min(ih)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih->flag); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih->flag); // count == 1 cmc_assert(ih_insert(ih, 10)); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert(ih_remove_min(ih)); cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); for (size_t i = 1000; i >= 1; i--) ih_insert(ih, i); @@ -434,89 +434,89 @@ CMC_CREATE_UNIT(IntervalHeap, true, { struct intervalheap *ih = ih_new(100, ih_fval); cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; // clear ih_clear(ih); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); // customize - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; ih_customize(ih, NULL, NULL); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); // insert - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert(ih_insert(ih, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); // remove_max cmc_assert(ih_remove_max(ih)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); cmc_assert(!ih_remove_max(ih)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); // remove min cmc_assert(ih_insert(ih, 10)); cmc_assert(ih_remove_min(ih)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); cmc_assert(!ih_remove_min(ih)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); // update_max cmc_assert(!ih_update_max(ih, 20)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); cmc_assert(ih_insert(ih, 10)); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert(ih_update_max(ih, 20)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); // update_min - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert(ih_update_min(ih, 20)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); cmc_assert(ih_remove_min(ih)); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert(!ih_update_max(ih, 20)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); // max min - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, (size_t){ 0 }, ih_max(ih)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, (size_t){ 0 }, ih_min(ih)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); cmc_assert(ih_insert(ih, 10)); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 10, ih_max(ih)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 10, ih_min(ih)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); // contains - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; cmc_assert(ih_contains(ih, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); // copy_of - ih->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; struct intervalheap *ih2 = ih_copy_of(ih); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih2)); // equals - ih->flag = cmc_flags.ERROR; - ih2->flag = cmc_flags.ERROR; + ih->flag = CMC_FLAG_ERROR; + ih2->flag = CMC_FLAG_ERROR; cmc_assert(ih_equals(ih, ih2)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih)); - cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih2)); ih_free(ih); ih_free(ih2); diff --git a/tests/main/unt/linkedlist.c b/tests/main/unt/linkedlist.c index 7e5113a..8962a63 100644 --- a/tests/main/unt/linkedlist.c +++ b/tests/main/unt/linkedlist.c @@ -85,133 +85,133 @@ CMC_CREATE_UNIT(LinkedList, true, { struct linkedlist *ll = ll_new(ll_fval); cmc_assert_not_equals(ptr, NULL, ll); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // clear - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; ll_clear(ll); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // customize - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; ll_customize(ll, NULL, NULL); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // push_front - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; cmc_assert(ll_push_front(ll, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // push_at - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; cmc_assert(ll_push_at(ll, 10, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); cmc_assert(!ll_push_at(ll, 10, 300)); - cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); // push_back - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; cmc_assert(ll_push_back(ll, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); ll_clear(ll); // pop_front - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; cmc_assert(!ll_pop_front(ll)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); cmc_assert(ll_push_back(ll, 10)); cmc_assert(ll_pop_front(ll)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // pop_at cmc_assert(!ll_pop_at(ll, 0)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); cmc_assert(ll_push_front(ll, 10)); cmc_assert(!ll_pop_at(ll, 1)); - cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); cmc_assert(ll_pop_at(ll, 0)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // pop_back - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; cmc_assert(!ll_pop_front(ll)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); cmc_assert(ll_push_back(ll, 10)); cmc_assert(ll_pop_front(ll)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); ll_clear(ll); // front ll_front(ll); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); cmc_assert(ll_push_front(ll, 10)); - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; ll_front(ll); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); ll_clear(ll); // back ll_back(ll); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); cmc_assert(ll_push_front(ll, 10)); - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; ll_back(ll); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); ll_clear(ll); // get get_ref ll_get(ll, 0); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll)); - ll->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); + ll->flag = CMC_FLAG_ERROR; ll_get_ref(ll, 0); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); cmc_assert(ll_push_at(ll, 10, 0)); - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; ll_get(ll, 0); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); ll_get(ll, 1); - cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); ll_get_ref(ll, 0); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); ll_get_ref(ll, 1); - cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); // contains cmc_assert(ll_contains(ll, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // copy_of - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; struct linkedlist *ll2 = ll_copy_of(ll); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll2)); // equals - ll->flag = cmc_flags.ERROR; - ll2->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; + ll2->flag = CMC_FLAG_ERROR; cmc_assert(ll_equals(ll, ll2)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll2)); ll_clear(ll); // get_node struct linkedlist_node *n = ll_get_node(ll, 0); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); cmc_assert(ll_push_at(ll, 10, 0)); n = ll_get_node(ll, 0); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); n = ll_get_node(ll, 1); - cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); // functions relative to node ll_clear(ll); @@ -220,35 +220,35 @@ CMC_CREATE_UNIT(LinkedList, true, { cmc_assert_not_equals(ptr, NULL, n); // add_next - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; cmc_assert(ll_add_next(ll, n, 11)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // add_prev - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; cmc_assert(ll_add_prev(ll, n, 9)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // del_next n = ll_next_node(n); cmc_assert(!ll_del_next(ll, n)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, ll_flag(ll)); n = ll_prev_node(n); cmc_assert(ll_del_next(ll, n)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // del_prev n = ll_prev_node(n); cmc_assert(!ll_del_prev(ll, n)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, ll_flag(ll)); n = ll_next_node(n); cmc_assert(ll_del_prev(ll, n)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); // del_curr - ll->flag = cmc_flags.ERROR; + ll->flag = CMC_FLAG_ERROR; cmc_assert(ll_del_curr(ll, n)); - cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); ll_free(ll); ll_free(ll2); diff --git a/tests/main/unt/list.c b/tests/main/unt/list.c index c98d0d2..6beae16 100644 --- a/tests/main/unt/list.c +++ b/tests/main/unt/list.c @@ -316,178 +316,178 @@ CMC_CREATE_UNIT(List, true, { struct list *l = l_new(100, l_fval); cmc_assert_not_equals(ptr, NULL, l); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // clear - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; l_clear(l); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // customize - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; l_customize(l, NULL, NULL); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // push_front - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; cmc_assert(l_push_front(l, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // push_at cmc_assert(!l_push_at(l, 5, 2)); - cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); cmc_assert(l_push_at(l, 5, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // push_back - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; cmc_assert(l_push_back(l, 0)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // pop_front - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; cmc_assert(l_pop_front(l)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); l_clear(l); cmc_assert(!l_pop_front(l)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); // pop_back cmc_assert(l_push_front(l, 10)); - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; cmc_assert(l_pop_back(l)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); cmc_assert(!l_pop_front(l)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); // pop_at - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; cmc_assert(!l_pop_at(l, 0)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); cmc_assert(l_push_back(l, 10)); cmc_assert(!l_pop_at(l, 1)); - cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); cmc_assert(l_pop_at(l, 0)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // seq_push_front cmc_assert(!l_seq_push_front(l, NULL, 0)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); cmc_assert(l_seq_push_front(l, (size_t[2]){ 1, 2 }, 2)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // seq_push_at cmc_assert(!l_seq_push_at(l, NULL, 0, 0)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); cmc_assert(!l_seq_push_at(l, (size_t[2]){ 1, 2 }, 2, 10)); - cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); cmc_assert(l_seq_push_at(l, (size_t[2]){ 1, 2 }, 2, l_count(l) - 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // seq_push_back cmc_assert(!l_seq_push_back(l, NULL, 0)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); cmc_assert(l_seq_push_back(l, (size_t[2]){ 1, 2 }, 2)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // seq_pop_at cmc_assert(!l_seq_pop_at(l, 10, 1)); - cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); cmc_assert(!l_seq_pop_at(l, 100, 200)); - cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); cmc_assert(l_seq_pop_at(l, 1, l_count(l) - 2)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // seq_sublist struct list *l2 = l_seq_sublist(l, 10, 1); cmc_assert_equals(ptr, NULL, l2); - cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); l2 = l_seq_sublist(l, 100, 200); cmc_assert_equals(ptr, NULL, l2); - cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); l2 = l_seq_sublist(l, 0, l_count(l) - 1); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l2)); l_clear(l); // l_front l_front(l); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); cmc_assert(l_push_back(l, 10)); - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; l_front(l); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); l_clear(l); // l_back l_back(l); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); cmc_assert(l_push_back(l, 10)); - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; l_back(l); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); l_clear(l); // get, get_ref l_get(l, 0); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l)); - l->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); + l->flag = CMC_FLAG_ERROR; l_get_ref(l, 0); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); cmc_assert(l_push_back(l, 10)); l_get(l, 1); - cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l)); - l->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); + l->flag = CMC_FLAG_ERROR; l_get_ref(l, 1); - cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); l_get(l, 0); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); - l->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + l->flag = CMC_FLAG_ERROR; l_get_ref(l, 0); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // index_of - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; l_index_of(l, 10, false); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // contains - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; cmc_assert(l_contains(l, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); // copy_of - l->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; struct list *l3 = l_copy_of(l); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l3)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l3)); // equals - l->flag = cmc_flags.ERROR; - l3->flag = cmc_flags.ERROR; + l->flag = CMC_FLAG_ERROR; + l3->flag = CMC_FLAG_ERROR; cmc_assert(l_equals(l, l3)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l)); - cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l3)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l3)); l_free(l); l_free(l2); diff --git a/tests/main/unt/queue.c b/tests/main/unt/queue.c index f988730..4fd0e3f 100644 --- a/tests/main/unt/queue.c +++ b/tests/main/unt/queue.c @@ -420,57 +420,57 @@ CMC_CREATE_UNIT(Queue, true, { struct queue *q = q_new(100, q_fval); cmc_assert_not_equals(ptr, NULL, q); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); // clear - q->flag = cmc_flags.ERROR; + q->flag = CMC_FLAG_ERROR; q_clear(q); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); // customize - q->flag = cmc_flags.ERROR; + q->flag = CMC_FLAG_ERROR; q_customize(q, NULL, NULL); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); // enqueue - q->flag = cmc_flags.ERROR; + q->flag = CMC_FLAG_ERROR; q_enqueue(q, 10); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); // dequeue - q->flag = cmc_flags.ERROR; + q->flag = CMC_FLAG_ERROR; q_dequeue(q); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); q_dequeue(q); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, q_flag(q)); // peek - q->flag = cmc_flags.ERROR; + q->flag = CMC_FLAG_ERROR; q_peek(q); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, q_flag(q)); cmc_assert(q_enqueue(q, 10)); q_peek(q); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); // contains - q->flag = cmc_flags.ERROR; + q->flag = CMC_FLAG_ERROR; cmc_assert(q_contains(q, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); // copy_of - q->flag = cmc_flags.OK; + q->flag = CMC_FLAG_OK; struct queue *q2 = q_copy_of(q); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q2)); // equals - q->flag = cmc_flags.OK; - q2->flag = cmc_flags.OK; + q->flag = CMC_FLAG_OK; + q2->flag = CMC_FLAG_OK; cmc_assert(q_equals(q, q2)); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q)); - cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q2)); q_free(q); q_free(q2); diff --git a/tests/main/unt/sortedlist.c b/tests/main/unt/sortedlist.c index 68e23dc..58b967e 100644 --- a/tests/main/unt/sortedlist.c +++ b/tests/main/unt/sortedlist.c @@ -148,87 +148,87 @@ CMC_CREATE_UNIT(SortedList, true, { struct sortedlist *sl = sl_new(100, sl_fval); cmc_assert_not_equals(ptr, NULL, sl); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); // clear - sl->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; sl_clear(sl); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); // customize - sl->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; sl_customize(sl, NULL, NULL); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); // insert - sl->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; cmc_assert(sl_insert(sl, 10)); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); // remove cmc_assert(!sl_remove(sl, 2)); - cmc_assert_equals(int32_t, cmc_flags.RANGE, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, sl_flag(sl)); cmc_assert(sl_remove(sl, 0)); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); cmc_assert(!sl_remove(sl, 0)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl)); // max min - sl->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, (size_t){ 0 }, sl_max(sl)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl)); - sl->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl)); + sl->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, (size_t){ 0 }, sl_min(sl)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl)); cmc_assert(sl_insert(sl, 1)); - sl->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 1, sl_max(sl)); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); - sl->flag = cmc_flags.ERROR; + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); + sl->flag = CMC_FLAG_ERROR; cmc_assert_equals(size_t, 1, sl_min(sl)); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); // get - sl->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; sl_get(sl, 1); - cmc_assert_equals(int32_t, cmc_flags.RANGE, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_RANGE, sl_flag(sl)); sl_get(sl, 0); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); cmc_assert(sl_remove(sl, 0)); sl_get(sl, 0); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl)); // index_of cmc_assert(sl_insert(sl, 1)); sl_index_of(sl, 1, false); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); // contains cmc_assert(sl_contains(sl, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); // sort - sl->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; sl_sort(sl); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); // copy_of - sl->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; struct sortedlist *sl2 = sl_copy_of(sl); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl2)); // equals - sl->flag = cmc_flags.ERROR; - sl2->flag = cmc_flags.ERROR; + sl->flag = CMC_FLAG_ERROR; + sl2->flag = CMC_FLAG_ERROR; cmc_assert(sl_equals(sl, sl2)); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl)); - cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl2)); sl_free(sl); sl_free(sl2); diff --git a/tests/main/unt/stack.c b/tests/main/unt/stack.c index 8537d58..298773a 100644 --- a/tests/main/unt/stack.c +++ b/tests/main/unt/stack.c @@ -282,57 +282,57 @@ CMC_CREATE_UNIT(Stack, true, { struct stack *s = s_new(100, s_fval); cmc_assert_not_equals(ptr, NULL, s); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); // clear - s->flag = cmc_flags.ERROR; + s->flag = CMC_FLAG_ERROR; s_clear(s); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); // customize - s->flag = cmc_flags.ERROR; + s->flag = CMC_FLAG_ERROR; s_customize(s, NULL, NULL); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); // push - s->flag = cmc_flags.ERROR; + s->flag = CMC_FLAG_ERROR; cmc_assert(s_push(s, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); // pop - s->flag = cmc_flags.ERROR; + s->flag = CMC_FLAG_ERROR; cmc_assert(s_pop(s)); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); cmc_assert(!s_pop(s)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, s_flag(s)); // top - s->flag = cmc_flags.ERROR; + s->flag = CMC_FLAG_ERROR; s_top(s); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, s_flag(s)); cmc_assert(s_push(s, 1)); s_top(s); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); // contains - s->flag = cmc_flags.ERROR; + s->flag = CMC_FLAG_ERROR; cmc_assert(s_contains(s, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); // copy_of - s->flag = cmc_flags.ERROR; + s->flag = CMC_FLAG_ERROR; struct stack *s2 = s_copy_of(s); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s2)); // equals - s->flag = cmc_flags.ERROR; - s2->flag = cmc_flags.ERROR; + s->flag = CMC_FLAG_ERROR; + s2->flag = CMC_FLAG_ERROR; cmc_assert(s_equals(s, s2)); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s)); - cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s2)); s_free(s); s_free(s2); diff --git a/tests/main/unt/treemap.c b/tests/main/unt/treemap.c index 909224b..9ce8b79 100644 --- a/tests/main/unt/treemap.c +++ b/tests/main/unt/treemap.c @@ -49,90 +49,90 @@ CMC_CREATE_UNIT(TreeMap, true, { struct treemap *map = tm_new(tm_fkey, tm_fval); cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); // clear - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; tm_clear(map); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); // insert - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(tm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); cmc_assert(!tm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, tm_flag(map)); // update cmc_assert(!tm_update(map, 2, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map)); cmc_assert(tm_update(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); // remove cmc_assert(!tm_remove(map, 2, NULL)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map)); cmc_assert(tm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); cmc_assert(!tm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); // max min - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(!tm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(!tm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); cmc_assert(tm_insert(map, 1, 1)); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(tm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; cmc_assert(tm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); // get get_ref tm_get(map, 2); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map)); tm_get(map, 1); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); tm_get_ref(map, 2); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map)); tm_get_ref(map, 1); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); cmc_assert(tm_remove(map, 1, NULL)); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; tm_get(map, 1); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; tm_get_ref(map, 1); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); // copy_of - map->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; struct treemap *map2 = tm_copy_of(map); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map2)); // equals - map->flag = cmc_flags.ERROR; - map2->flag = cmc_flags.ERROR; + map->flag = CMC_FLAG_ERROR; + map2->flag = CMC_FLAG_ERROR; cmc_assert(tm_equals(map, map2)); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map)); - cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map2)); tm_free(map); tm_free(map2); diff --git a/tests/main/unt/treeset.c b/tests/main/unt/treeset.c index 46bc04e..eef1667 100644 --- a/tests/main/unt/treeset.c +++ b/tests/main/unt/treeset.c @@ -42,61 +42,61 @@ CMC_CREATE_UNIT(TreeSet, true, { struct treeset *set = ts_new(ts_fval); cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); // clear - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; ts_clear(set); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); // insert - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(ts_insert(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); cmc_assert(!ts_insert(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, ts_flag(set)); // remove cmc_assert(!ts_remove(set, 2)); - cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, ts_flag(set)); cmc_assert(ts_remove(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); cmc_assert(!ts_remove(set, 1)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set)); // max min - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(!ts_max(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set)); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(!ts_min(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.EMPTY, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set)); cmc_assert(ts_insert(set, 1)); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(ts_max(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; cmc_assert(ts_min(set, NULL)); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); // copy_of - set->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; struct treeset *set2 = ts_copy_of(set); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set)); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set2)); // equals - set->flag = cmc_flags.ERROR; - set2->flag = cmc_flags.ERROR; + set->flag = CMC_FLAG_ERROR; + set2->flag = CMC_FLAG_ERROR; cmc_assert(ts_equals(set, set2)); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set)); - cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set2)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); + cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set2)); ts_free(set); ts_free(set2); From 8e0183a7d78dc3fe7972091bf5f28e6ee77dae17 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 26 May 2020 14:21:23 -0300 Subject: [PATCH 05/51] Update autogen.py --- autogen.py | 57 +++++++++++++++++++++++------------------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/autogen.py b/autogen.py index 924c70b..73124b2 100644 --- a/autogen.py +++ b/autogen.py @@ -1,6 +1,7 @@ # A script that automatically expands the macros for code coverage import os +import sys import re import subprocess @@ -25,22 +26,22 @@ OUTPUT_DIR = './tests/main/src' collections = [ # type, header, pfx, sname, key, val - {'t': 'BITSET', 'h': '"cmc/bitset.h"', 'pfx': 'bs', 'sname': 'bitset', 'key': '', 'val': '' }, - {'t': 'DEQUE', 'h': '"cmc/deque.h"', 'pfx': 'd', 'sname': 'deque', 'key': '', 'val': 'size_t'}, - {'t': 'HASHBIDIMAP', 'h': '"cmc/hashbidimap.h"', 'pfx': 'hbm', 'sname': 'hashbidimap', 'key': 'size_t', 'val': 'size_t'}, - {'t': 'HASHMAP', 'h': '"cmc/hashmap.h"', 'pfx': 'hm', 'sname': 'hashmap', 'key': 'size_t', 'val': 'size_t'}, - {'t': 'HASHMULTIMAP', 'h': '"cmc/hashmultimap.h"', 'pfx': 'hmm', 'sname': 'hashmultimap', 'key': 'size_t', 'val': 'size_t'}, - {'t': 'HASHMULTISET', 'h': '"cmc/hashmultiset.h"', 'pfx': 'hms', 'sname': 'hashmultiset', 'key': '', 'val': 'size_t'}, - {'t': 'HASHSET', 'h': '"cmc/hashset.h"', 'pfx': 'hs', 'sname': 'hashset', 'key': '', 'val': 'size_t'}, - {'t': 'HEAP', 'h': '"cmc/heap.h"', 'pfx': 'h', 'sname': 'heap', 'key': '', 'val': 'size_t'}, - {'t': 'INTERVALHEAP', 'h': '"cmc/intervalheap.h"', 'pfx': 'ih', 'sname': 'intervalheap', 'key': '', 'val': 'size_t'}, - {'t': 'LINKEDLIST', 'h': '"cmc/linkedlist.h"', 'pfx': 'll', 'sname': 'linkedlist', 'key': '', 'val': 'size_t'}, - {'t': 'LIST', 'h': '"cmc/list.h"', 'pfx': 'l', 'sname': 'list', 'key': '', 'val': 'size_t'}, - {'t': 'QUEUE', 'h': '"cmc/queue.h"', 'pfx': 'q', 'sname': 'queue', 'key': '', 'val': 'size_t'}, - {'t': 'SORTEDLIST', 'h': '"cmc/sortedlist.h"', 'pfx': 'sl', 'sname': 'sortedlist', 'key': '', 'val': 'size_t'}, - {'t': 'STACK', 'h': '"cmc/stack.h"', 'pfx': 's', 'sname': 'stack', 'key': '', 'val': 'size_t'}, - {'t': 'TREEMAP', 'h': '"cmc/treemap.h"', 'pfx': 'tm', 'sname': 'treemap', 'key': 'size_t', 'val': 'size_t'}, - {'t': 'TREESET', 'h': '"cmc/treeset.h"', 'pfx': 'ts', 'sname': 'treeset', 'key': '', 'val': 'size_t'} + {'h': '"cmc/bitset.h"', 'LIB': 'CMC', 'COLLECTION': 'BITSET', 'PFX': 'bs', 'SNAME': 'bitset', 'SIZE': '', 'K': '', 'V': '' }, + {'h': '"cmc/deque.h"', 'LIB': 'CMC', 'COLLECTION': 'DEQUE', 'PFX': 'd', 'SNAME': 'deque', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/hashbidimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHBIDIMAP', 'PFX': 'hbm', 'SNAME': 'hashbidimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, + {'h': '"cmc/hashmap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMAP', 'PFX': 'hm', 'SNAME': 'hashmap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, + {'h': '"cmc/hashmultimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMULTIMAP', 'PFX': 'hmm', 'SNAME': 'hashmultimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, + {'h': '"cmc/hashmultiset.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMULTISET', 'PFX': 'hms', 'SNAME': 'hashmultiset', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/hashset.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHSET', 'PFX': 'hs', 'SNAME': 'hashset', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/heap.h"', 'LIB': 'CMC', 'COLLECTION': 'HEAP', 'PFX': 'h', 'SNAME': 'heap', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/intervalheap.h"', 'LIB': 'CMC', 'COLLECTION': 'INTERVALHEAP', 'PFX': 'ih', 'SNAME': 'intervalheap', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/linkedlist.h"', 'LIB': 'CMC', 'COLLECTION': 'LINKEDLIST', 'PFX': 'll', 'SNAME': 'linkedlist', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/list.h"', 'LIB': 'CMC', 'COLLECTION': 'LIST', 'PFX': 'l', 'SNAME': 'list', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/queue.h"', 'LIB': 'CMC', 'COLLECTION': 'QUEUE', 'PFX': 'q', 'SNAME': 'queue', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/sortedlist.h"', 'LIB': 'CMC', 'COLLECTION': 'SORTEDLIST', 'PFX': 'sl', 'SNAME': 'sortedlist', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/stack.h"', 'LIB': 'CMC', 'COLLECTION': 'STACK', 'PFX': 's', 'SNAME': 'stack', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc/treemap.h"', 'LIB': 'CMC', 'COLLECTION': 'TREEMAP', 'PFX': 'tm', 'SNAME': 'treemap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, + {'h': '"cmc/treeset.h"', 'LIB': 'CMC', 'COLLECTION': 'TREESET', 'PFX': 'ts', 'SNAME': 'treeset', 'SIZE': '', 'K': '', 'V': 'size_t'} ] # Create output directory @@ -50,23 +51,13 @@ if not os.path.exists(OUTPUT_DIR): for data in collections: file = open(TMP_FILE, 'w') - if data['key'] == '' and data['val'] == '': - # bitset, no K and no V - type_params = '' - elif data['key'] != '': - # maps, K and V - type_params = f', {data["key"]}, {data["val"]}' - else: - # only V - type_params = f', {data["val"]}' - file.write( f''' #include {data['h']} {UNIQUE_FLAG} - CMC_GENERATE_{data['t']}({data['pfx']}, {data['sname']}{type_params}) + CMC_{data['LIB']}_{data['COLLECTION']}_CORE(({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) {UNIQUE_FLAG} ''') @@ -81,24 +72,24 @@ for data in collections: if match is None: os.remove(TMP_FILE) - print('Didn\'t match FLAG. Probably because compilation failed.') + print('Didn\'t match FLAG. Probably because compilation failed.', file=sys.stderr) exit(1) - file = open(f'{OUTPUT_DIR}/{data["sname"]}.c', 'w') + file = open(f'{OUTPUT_DIR}/{data["SNAME"]}.c', 'w') file.write( - f'''#ifndef CMC_TEST_SRC_{data['t']} - #define CMC_TEST_SRC_{data['t']} + f'''#ifndef CMC_TEST_SRC_{data['COLLECTION']} + #define CMC_TEST_SRC_{data['COLLECTION']} #include {data["h"]}\n{match.group("code")} - #endif /* CMC_TEST_SRC_{data['t']} */ + #endif /* CMC_TEST_SRC_{data['COLLECTION']} */ ''') file.flush() file.close() - print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{data["sname"]}.c') + print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{data["SNAME"]}.c') os.remove(TMP_FILE) From 720e55bfcc022fad90645c9c22b6e49e03c8755a Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 26 May 2020 15:32:34 -0300 Subject: [PATCH 06/51] Moved params to core and some code cleanup --- Makefile | 25 +++++------------------ autogen.py | 2 +- src/cmc/treeset.h | 7 +++---- src/cor/core.h | 45 ++++++++++++++++++++++++++++++++++++++++- src/cor/params.h | 51 ----------------------------------------------- 5 files changed, 53 insertions(+), 77 deletions(-) delete mode 100644 src/cor/params.h diff --git a/Makefile b/Makefile index 971ce61..ecbba47 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,13 @@ # This file is useful to format all the source files and header in this library using clang-format -.PHONY: all cmc dev sac utl tests FORCE +ARGS = --verbose -all: cmc cor dev ext sac utl tests +all: src tests -cmc: FORCE - clang-format --style=file -i ./src/cmc/*.h - -cor: FORCE - clang-format --style=file -i ./src/cor/*.h - -dev: FORCE - clang-format --style=file -i ./src/dev/*.h - -ext: FORCE - clang-format --style=file -i ./src/ext/**/*.h - -sac: FORCE - clang-format --style=file -i ./src/sac/*.h - -utl: FORCE - clang-format --style=file -i ./src/utl/*.h +src: FORCE + find ./src/ -iname *.h | xargs clang-format --style=file --verbose -i tests: FORCE - clang-format --style=file -i ./tests/main/unt/*.c ./tests/main/main.c ./tests/*.c + find ./tests/ -iname *.c -o -iname *.h | xargs clang-format --style=file --verbose -i FORCE: diff --git a/autogen.py b/autogen.py index 73124b2..fe8b08d 100644 --- a/autogen.py +++ b/autogen.py @@ -95,5 +95,5 @@ os.remove(TMP_FILE) # Format all files print('Formating files...') -subprocess.call(['clang-format', '--style=file', '-i', f'{OUTPUT_DIR}/*.c']) +subprocess.call(['clang-format', '--style=file', '-i', f'{OUTPUT_DIR}/*.c', '--verbose']) print('Done') diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index eb853e3..9d4ed3e 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -676,10 +676,9 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " { \ if (_set_->f_val->cpy) \ CMC_(PFX, _insert) \ - (result, \ - _set_->f_val->cpy(CMC_(PFX, _iter_value)(&iter))); \ - else \ - CMC_(PFX, _insert)(result, CMC_(PFX, _iter_value)(&iter)); \ + (result, _set_->f_val->cpy(CMC_(PFX, _iter_value)(&iter))); \ + else CMC_(PFX, _insert)(result, \ + CMC_(PFX, _iter_value)(&iter)); \ } \ } \ \ diff --git a/src/cor/core.h b/src/cor/core.h index 36d0bd9..8eca039 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -10,6 +10,13 @@ /** * Core includes and macros for the entire library. + * + * Here you will find: + * - CMC_ + * - CMC_TO_STRING + * - CMC_INTERNAL_PREFIX_[ITER|NODE|ENTRY|FKEY|FVAL] + * - CMC_DEF_[ITER|NODE|ENTRY|FKEY|FVAL] + * - CMC_PARAM_[PFX|SNAME|SIZE|K|V] */ #ifndef CMC_COR_CORE_H @@ -25,7 +32,6 @@ #include "alloc.h" #include "callbacks.h" #include "flags.h" -#include "params.h" #define CMC__(A, B) A##B #define CMC_(A, B) CMC__(A, B) @@ -53,6 +59,43 @@ #define CMC_DEF_FVAL(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FVAL) #define CMC_DEF_FKEY(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FKEY) +/** + * A PARAM is a unified way to pass arguments to all macros that generate code. + * It is a tuple that contains the following parameters in order: + * + * PFX - Functions prefix + * SNAME - `struct` name + * SIZE - Size for SAC library + * K - Key type + * V - Value type + * + * PARAM := (PFX, SNAME, SIZE, K, V) + */ + +// clang-format off +/* +for i in range(5): + print(f"#define CMC_TUP_{i}_({', '.join(chr(x) for x in range(65, 65 + i + 1))}, ...) {chr(65 + i)}\n#define CMC_TUP_{i}(TUP) CMC_TUP_{i}_ TUP") +*/ +// clang-format on + +#define CMC_TUP_0_(A, ...) A +#define CMC_TUP_0(TUP) CMC_TUP_0_ TUP +#define CMC_TUP_1_(A, B, ...) B +#define CMC_TUP_1(TUP) CMC_TUP_1_ TUP +#define CMC_TUP_2_(A, B, C, ...) C +#define CMC_TUP_2(TUP) CMC_TUP_2_ TUP +#define CMC_TUP_3_(A, B, C, D, ...) D +#define CMC_TUP_3(TUP) CMC_TUP_3_ TUP +#define CMC_TUP_4_(A, B, C, D, E, ...) E +#define CMC_TUP_4(TUP) CMC_TUP_4_ TUP + +#define CMC_PARAM_PFX CMC_TUP_0 +#define CMC_PARAM_SNAME CMC_TUP_1 +#define CMC_PARAM_SIZE CMC_TUP_2 +#define CMC_PARAM_K CMC_TUP_3 +#define CMC_PARAM_V CMC_TUP_4 + /** * struct cmc_string * diff --git a/src/cor/params.h b/src/cor/params.h deleted file mode 100644 index 61d6091..0000000 --- a/src/cor/params.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * params.h - * - * Creation Date: 25/05/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * A PARAM is a unified way to pass arguments to all macros that generate code. - * It is a tuple that contains the following parameters in order: - * - * PFX - Functions prefix - * SNAME - `struct` name - * SIZE - Size for SAC library - * K - Key type - * V - Value type - * - * PARAM := (PFX, SNAME, SIZE, K, V) - */ - -#ifndef CMC_COR_PARAMS_H -#define CMC_COR_PARAMS_H - -// clang-format off -/* -for i in range(5): - print(f"#define CMC_TUP_{i}_({', '.join(chr(x) for x in range(65, 65 + i + 1))}, ...) {chr(65 + i)}\n#define CMC_TUP_{i}(TUP) CMC_TUP_{i}_ TUP") -*/ -// clang-format on - -#define CMC_TUP_0_(A, ...) A -#define CMC_TUP_0(TUP) CMC_TUP_0_ TUP -#define CMC_TUP_1_(A, B, ...) B -#define CMC_TUP_1(TUP) CMC_TUP_1_ TUP -#define CMC_TUP_2_(A, B, C, ...) C -#define CMC_TUP_2(TUP) CMC_TUP_2_ TUP -#define CMC_TUP_3_(A, B, C, D, ...) D -#define CMC_TUP_3(TUP) CMC_TUP_3_ TUP -#define CMC_TUP_4_(A, B, C, D, E, ...) E -#define CMC_TUP_4(TUP) CMC_TUP_4_ TUP - -#define CMC_PARAM_PFX CMC_TUP_0 -#define CMC_PARAM_SNAME CMC_TUP_1 -#define CMC_PARAM_SIZE CMC_TUP_2 -#define CMC_PARAM_K CMC_TUP_3 -#define CMC_PARAM_V CMC_TUP_4 - -#endif /* CMC_COR_PARAMS_H */ From 85bef64551564f50a0ebdc011ab64b5d09ce29e3 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 26 May 2020 17:25:43 -0300 Subject: [PATCH 07/51] Fast forward changes on new way to generate macros --- src/cor/core.h | 57 ++++++++++++----------- src/ext/cmc/deque.h | 6 ++- src/ext/cmc/hashbidimap.h | 9 ++++ src/ext/cmc/hashmap.h | 6 ++- src/macro_collections.h | 95 +++++++++++++++++++++++++++++---------- 5 files changed, 120 insertions(+), 53 deletions(-) diff --git a/src/cor/core.h b/src/cor/core.h index 8eca039..91e6460 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -60,25 +60,8 @@ #define CMC_DEF_FKEY(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FKEY) /** - * A PARAM is a unified way to pass arguments to all macros that generate code. - * It is a tuple that contains the following parameters in order: - * - * PFX - Functions prefix - * SNAME - `struct` name - * SIZE - Size for SAC library - * K - Key type - * V - Value type - * - * PARAM := (PFX, SNAME, SIZE, K, V) + * Code to get specific arguments from tuples. */ - -// clang-format off -/* -for i in range(5): - print(f"#define CMC_TUP_{i}_({', '.join(chr(x) for x in range(65, 65 + i + 1))}, ...) {chr(65 + i)}\n#define CMC_TUP_{i}(TUP) CMC_TUP_{i}_ TUP") -*/ -// clang-format on - #define CMC_TUP_0_(A, ...) A #define CMC_TUP_0(TUP) CMC_TUP_0_ TUP #define CMC_TUP_1_(A, B, ...) B @@ -90,6 +73,18 @@ for i in range(5): #define CMC_TUP_4_(A, B, C, D, E, ...) E #define CMC_TUP_4(TUP) CMC_TUP_4_ TUP +/** + * A PARAM is a unified way to pass arguments to all macros that generate code. + * It is a tuple that contains the following parameters in order: + * + * PFX - Functions prefix + * SNAME - `struct` name + * SIZE - Size for SAC library + * K - Key type + * V - Value type + * + * PARAM := (PFX, SNAME, SIZE, K, V) + */ #define CMC_PARAM_PFX CMC_TUP_0 #define CMC_PARAM_SNAME CMC_TUP_1 #define CMC_PARAM_SIZE CMC_TUP_2 @@ -97,15 +92,25 @@ for i in range(5): #define CMC_PARAM_V CMC_TUP_4 /** - * struct cmc_string + * A __VA_ARGS__ argument counter. This argument counter is slightly shifted: * - * Used by all collections when calling the to_string function. + * CMC_NARG(HELLO) -> 0 + * CMC_NARG(HELLO,) -> 1 + * CMC_NARG(HELLO, WORLD,) -> 2 */ -struct cmc_string -{ - char s[400]; -}; - -static const size_t cmc_string_len = 400; +#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N()) +#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__) +#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ + _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \ + _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ + _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ + _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ + _62, _63, N, ...) \ + N +#define CMC_SEQ_N() \ + 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \ + 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \ + 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 #endif /* CMC_COR_CORE_H */ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 72fdeac..9b91281 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -1,7 +1,7 @@ /** * deque.h * - * Creation Date: 25/05/2019 + * Creation Date: 25/05/2020 * * Authors: * Leonardo Vencovsky (https://github.com/LeoVen) @@ -17,7 +17,9 @@ #ifndef CMC_EXT_CMC_DEQUE_H #define CMC_EXT_CMC_DEQUE_H -#include "../../cor/params.h" +#include "../../cor/core.h" + +#define CMC_EXT_CMC_DEQUE_PARTS INIT, /** * INIT diff --git a/src/ext/cmc/hashbidimap.h b/src/ext/cmc/hashbidimap.h index e69de29..aa2cfa5 100644 --- a/src/ext/cmc/hashbidimap.h +++ b/src/ext/cmc/hashbidimap.h @@ -0,0 +1,9 @@ +/** + * hashbidimap.h + * + * Creation Date: 26/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 26837d5..48e1987 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -1,7 +1,7 @@ /** * hashmap.h * - * Creation Date: 25/05/2019 + * Creation Date: 25/05/2020 * * Authors: * Leonardo Vencovsky (https://github.com/LeoVen) @@ -17,7 +17,9 @@ #ifndef CMC_EXT_CMC_HASHMAP_H #define CMC_EXT_CMC_HASHMAP_H -#include "../../cor/params.h" +#include "../../cor/core.h" + +#define CMC_EXT_CMC_HASHMAP_PARTS INIT, ITER /** * INIT diff --git a/src/macro_collections.h b/src/macro_collections.h index 329d0b2..35c7b5b 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -11,25 +11,6 @@ #ifndef CMC_MACRO_COLLECTIONS_H #define CMC_MACRO_COLLECTIONS_H -#define CMC_CONCAT_(C, T) CMC_WRAPGEN_##C##_##T - -#define CMC_CONCAT(C, T) CMC_CONCAT_(C, T) - -#define CMC_COLLECTION_GENERATE(C, PFX, SNAME, K, V) \ - CMC_COLLECTION_GENERATE_HEADER(C, PFX, SNAME, K, V) \ - CMC_COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, K, V) - -#define CMC_COLLECTION_GENERATE_HEADER(C, PFX, SNAME, K, V) \ - CMC_CONCAT(C, HEADER)(PFX, SNAME, K, V) - -#define CMC_COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, K, V) \ - CMC_CONCAT(C, SOURCE)(PFX, SNAME, K, V) - -#include "cor/bitset.h" /* Added in 20/05/2020 */ -#include "cor/core.h" /* Added in 17/03/2020 */ -#include "cor/flags.h" /* Added in 14/05/2020 */ -#include "cor/hashtable.h" /* Added in 17/03/2020 */ - #include "cmc/bitset.h" /* Added in 30/04/2020 */ #include "cmc/deque.h" /* Added in 20/03/2019 */ #include "cmc/hashbidimap.h" /* Added in 26/09/2019 */ @@ -46,10 +27,13 @@ #include "cmc/stack.h" /* Added in 14/02/2019 */ #include "cmc/treemap.h" /* Added in 28/03/2019 */ #include "cmc/treeset.h" /* Added in 27/03/2019 */ - -#include "sac/queue.h" -#include "sac/stack.h" - +#include "cor/alloc.h" /* Added in 24/05/2020 */ +#include "cor/bitset.h" /* Added in 20/05/2020 */ +#include "cor/callbacks.h" /* Added in 24/05/2020 */ +#include "cor/core.h" /* Added in 17/03/2020 */ +#include "cor/flags.h" /* Added in 14/05/2020 */ +#include "cor/hashtable.h" /* Added in 17/03/2020 */ +#include "ext/cmc/deque.h" /* Added in 25/05/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ #include "utl/futils.h" /* Added in 15/04/2020 */ @@ -59,4 +43,69 @@ #include "utl/thread.h" /* Added in 14/05/2020 */ #include "utl/timer.h" /* Added in 12/04/2019 */ +/** + * Generate a specific part of a collection + */ +#define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE)(PARAMS) +#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE) \ + CMC_##LIB##_##COLLECTION##_##PART##_##FILE + +/** + * Generate everything provided by a collection included in ext + */ +#define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \ + C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \ + C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) + +#define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, \ + C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) + +#define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, \ + C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) + +/* Gets the macro with all EXT parts of a collection */ +#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \ + CMC_EXT_##LIB##_##COLLECTION##_PARTS + +#define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \ + CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \ + (LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) + +#define CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, PART, ...) +#define CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_10(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ + CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) + #endif /* CMC_MACRO_COLLECTIONS_H */ From 77a7178857ffeab65bb55c770ec32d02aca1155b Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 27 May 2020 00:48:34 -0300 Subject: [PATCH 08/51] Added ./cor/ftable.h and fast forward changes --- src/cmc/deque.h | 1234 ++++++++++++++----------------------- src/cmc/hashmap.h | 32 - src/cor/core.h | 23 +- src/cor/ftable.h | 28 + src/ext/cmc/deque.h | 345 ++++++++++- src/ext/cmc/hashbidimap.h | 12 + src/ext/cmc/hashmap.h | 88 ++- src/macro_collections.h | 29 + 8 files changed, 961 insertions(+), 830 deletions(-) create mode 100644 src/cor/ftable.h diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 5b6dffa..ecbf4ae 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -70,769 +70,485 @@ static const char *cmc_cmc_string_fmt_deque = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Deque Structure */ \ - struct SNAME \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ - \ - /* Current circular array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Index representing the front of the deque */ \ - size_t front; \ - \ - /* Index representing the back of the deque */ \ - size_t back; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Deque Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target deque */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _deque_); \ - void CMC_(PFX, _free)(struct SNAME * _deque_); \ - void CMC_(PFX, _release)(struct SNAME _deque_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _deque_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _deque_); \ - V CMC_(PFX, _back)(struct SNAME * _deque_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _deque_); \ - bool CMC_(PFX, _full)(struct SNAME * _deque_); \ - size_t CMC_(PFX, _count)(struct SNAME * _deque_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \ - int CMC_(PFX, _flag)(struct SNAME * _deque_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \ - bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _deque_); \ - bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Deque Structure */ \ + struct SNAME \ + { \ + /* Dynamic circular array of elements */ \ + V *buffer; \ + \ + /* Current circular array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Index representing the front of the deque */ \ + size_t front; \ + \ + /* Index representing the back of the deque */ \ + size_t back; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ + \ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ + \ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ + \ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ + \ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ + \ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _deque_); \ + void CMC_(PFX, _free)(struct SNAME * _deque_); \ + void CMC_(PFX, _release)(struct SNAME _deque_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _deque_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _deque_); \ + V CMC_(PFX, _back)(struct SNAME * _deque_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _deque_); \ + bool CMC_(PFX, _full)(struct SNAME * _deque_); \ + size_t CMC_(PFX, _count)(struct SNAME * _deque_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \ + int CMC_(PFX, _flag)(struct SNAME * _deque_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \ + bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_deque_) \ - return NULL; \ - \ - _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_deque_->buffer) \ - { \ - alloc->free(_deque_); \ - return NULL; \ - } \ - \ - _deque_->capacity = capacity; \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - _deque_->flag = CMC_FLAG_OK; \ - _deque_->f_val = f_val; \ - _deque_->alloc = alloc; \ - _deque_->callbacks = callbacks; \ - \ - return _deque_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _deque_) \ - { \ - if (_deque_->f_val->free) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - _deque_->f_val->free(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \ - \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _deque_) \ - { \ - if (_deque_->f_val->free) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - _deque_->f_val->free(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - _deque_->alloc->free(_deque_->buffer); \ - _deque_->alloc->free(_deque_); \ - } \ - \ - void CMC_(PFX, _release)(struct SNAME _deque_) \ - { \ - if (_deque_.f_val->free) \ - { \ - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ - { \ - _deque_.f_val->free(_deque_.buffer[i]); \ - \ - i = (i + 1) % _deque_.capacity; \ - } \ - } \ - \ - _deque_.alloc->free(_deque_.buffer); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _deque_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _deque_->alloc = &cmc_alloc_node_default; \ - else \ - _deque_->alloc = alloc; \ - \ - _deque_->callbacks = callbacks; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \ - { \ - if (CMC_(PFX, _full)(_deque_)) \ - { \ - if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ - return false; \ - } \ - \ - _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 \ - : _deque_->front - 1; \ - \ - _deque_->buffer[_deque_->front] = value; \ - \ - _deque_->count++; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->create) \ - _deque_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \ - { \ - if (CMC_(PFX, _full)(_deque_)) \ - { \ - if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ - return false; \ - } \ - \ - _deque_->buffer[_deque_->back] = value; \ - \ - _deque_->back = \ - (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ - \ - _deque_->count++; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->create) \ - _deque_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _deque_->buffer[_deque_->front] = (V){ 0 }; \ - \ - _deque_->front = (_deque_->front == _deque_->capacity - 1) \ - ? 0 \ - : _deque_->front + 1; \ - \ - _deque_->count--; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->delete) \ - _deque_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _deque_->back = \ - (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ - \ - _deque_->buffer[_deque_->back] = (V){ 0 }; \ - \ - _deque_->count--; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->delete) \ - _deque_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _front)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return _deque_->buffer[_deque_->front]; \ - } \ - \ - V CMC_(PFX, _back)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 \ - : _deque_->back - 1]; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \ - { \ - _deque_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _deque_) \ - { \ - return _deque_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _deque_) \ - { \ - return _deque_->count >= _deque_->capacity; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _deque_) \ - { \ - return _deque_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \ - { \ - return _deque_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _deque_) \ - { \ - return _deque_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \ - { \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->capacity == capacity) \ - goto success; \ - \ - if (capacity < _deque_->count) \ - { \ - _deque_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - { \ - _deque_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - new_buffer[j] = _deque_->buffer[i]; \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - \ - _deque_->alloc->free(_deque_->buffer); \ - \ - _deque_->buffer = new_buffer; \ - _deque_->capacity = capacity; \ - _deque_->front = 0; \ - _deque_->back = _deque_->count; \ - \ - success: \ - \ - if (_deque_->callbacks && _deque_->callbacks->resize) \ - _deque_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, \ - _deque_->alloc, _deque_->callbacks); \ - \ - if (!result) \ - { \ - _deque_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_deque_->f_val->cpy) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - else \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - result->buffer[j] = _deque_->buffer[i]; \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - result->count = _deque_->count; \ - result->front = 0; \ - result->back = _deque_->count; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \ - { \ - _deque1_->flag = CMC_FLAG_OK; \ - _deque2_->flag = CMC_FLAG_OK; \ - \ - if (_deque1_->count != _deque2_->count) \ - return false; \ - \ - size_t i, j, k; \ - for (i = _deque1_->front, j = _deque2_->front, k = 0; \ - k < _deque1_->count; k++) \ - { \ - if (_deque1_->f_val->cmp(_deque1_->buffer[i], \ - _deque2_->buffer[j]) != 0) \ - return false; \ - \ - i = (i + 1) % _deque1_->capacity; \ - j = (j + 1) % _deque2_->capacity; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _deque_) \ - { \ - struct cmc_string str; \ - struct SNAME *d_ = _deque_; \ - \ - int n = \ - snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_deque, #SNAME, \ - #V, d_, d_->buffer, d_->capacity, d_->count, d_->front, \ - d_->back, d_->flag, d_->f_val, d_->alloc, d_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \ - return false; \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->front; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - if (iter.target->back == 0) \ - iter.cursor = iter.target->capacity - 1; \ - else \ - iter.cursor = iter.target->back - 1; \ - \ - iter.index = iter.target->count - 1; \ - } \ - else \ - { \ - iter.cursor = 0; \ - iter.index = 0; \ - } \ - \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - if (iter->target->back == 0) \ - iter->cursor = iter->target->capacity - 1; \ - else \ - iter->cursor = iter->target->back - 1; \ - \ - iter->index = iter->target->count - 1; \ - \ - iter->start = false; \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \ - : iter->cursor - 1; \ - iter->index--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index += steps; \ - iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index -= steps; \ - \ - /* Prevent underflow */ \ - if (iter->cursor < steps) \ - iter->cursor += iter->target->capacity; \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ +#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \ + \ + /* Implementation Detail Functions */ \ + /* None */ \ + \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ + } \ + \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ + \ + if (!f_val) \ + return NULL; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_deque_) \ + return NULL; \ + \ + _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \ + \ + if (!_deque_->buffer) \ + { \ + alloc->free(_deque_); \ + return NULL; \ + } \ + \ + _deque_->capacity = capacity; \ + _deque_->count = 0; \ + _deque_->front = 0; \ + _deque_->back = 0; \ + _deque_->flag = CMC_FLAG_OK; \ + _deque_->f_val = f_val; \ + _deque_->alloc = alloc; \ + _deque_->callbacks = callbacks; \ + \ + return _deque_; \ + } \ + \ + void CMC_(PFX, _clear)(struct SNAME * _deque_) \ + { \ + if (_deque_->f_val->free) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + _deque_->f_val->free(_deque_->buffer[i]); \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + \ + memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \ + \ + _deque_->count = 0; \ + _deque_->front = 0; \ + _deque_->back = 0; \ + \ + _deque_->flag = CMC_FLAG_OK; \ + } \ + \ + void CMC_(PFX, _free)(struct SNAME * _deque_) \ + { \ + if (_deque_->f_val->free) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + _deque_->f_val->free(_deque_->buffer[i]); \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + \ + _deque_->alloc->free(_deque_->buffer); \ + _deque_->alloc->free(_deque_); \ + } \ + \ + void CMC_(PFX, _release)(struct SNAME _deque_) \ + { \ + if (_deque_.f_val->free) \ + { \ + for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ + { \ + _deque_.f_val->free(_deque_.buffer[i]); \ + \ + i = (i + 1) % _deque_.capacity; \ + } \ + } \ + \ + _deque_.alloc->free(_deque_.buffer); \ + } \ + \ + void CMC_(PFX, _customize)(struct SNAME * _deque_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + if (!alloc) \ + _deque_->alloc = &cmc_alloc_node_default; \ + else \ + _deque_->alloc = alloc; \ + \ + _deque_->callbacks = callbacks; \ + \ + _deque_->flag = CMC_FLAG_OK; \ + } \ + \ + bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \ + { \ + if (CMC_(PFX, _full)(_deque_)) \ + { \ + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ + return false; \ + } \ + \ + _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 \ + : _deque_->front - 1; \ + \ + _deque_->buffer[_deque_->front] = value; \ + \ + _deque_->count++; \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->create) \ + _deque_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \ + { \ + if (CMC_(PFX, _full)(_deque_)) \ + { \ + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ + return false; \ + } \ + \ + _deque_->buffer[_deque_->back] = value; \ + \ + _deque_->back = \ + (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ + \ + _deque_->count++; \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->create) \ + _deque_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + _deque_->buffer[_deque_->front] = (V){ 0 }; \ + \ + _deque_->front = (_deque_->front == _deque_->capacity - 1) \ + ? 0 \ + : _deque_->front + 1; \ + \ + _deque_->count--; \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->delete) \ + _deque_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + _deque_->back = \ + (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ + \ + _deque_->buffer[_deque_->back] = (V){ 0 }; \ + \ + _deque_->count--; \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->delete) \ + _deque_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _front)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->read) \ + _deque_->callbacks->read(); \ + \ + return _deque_->buffer[_deque_->front]; \ + } \ + \ + V CMC_(PFX, _back)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->callbacks && _deque_->callbacks->read) \ + _deque_->callbacks->read(); \ + \ + return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 \ + : _deque_->back - 1]; \ + } \ + \ + bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \ + { \ + _deque_->flag = CMC_FLAG_OK; \ + \ + bool result = false; \ + \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \ + { \ + result = true; \ + break; \ + } \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + \ + if (_deque_->callbacks && _deque_->callbacks->read) \ + _deque_->callbacks->read(); \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _empty)(struct SNAME * _deque_) \ + { \ + return _deque_->count == 0; \ + } \ + \ + bool CMC_(PFX, _full)(struct SNAME * _deque_) \ + { \ + return _deque_->count >= _deque_->capacity; \ + } \ + \ + size_t CMC_(PFX, _count)(struct SNAME * _deque_) \ + { \ + return _deque_->count; \ + } \ + \ + size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \ + { \ + return _deque_->capacity; \ + } \ + \ + int CMC_(PFX, _flag)(struct SNAME * _deque_) \ + { \ + return _deque_->flag; \ + } \ + \ + bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \ + { \ + _deque_->flag = CMC_FLAG_OK; \ + \ + if (_deque_->capacity == capacity) \ + goto success; \ + \ + if (capacity < _deque_->count) \ + { \ + _deque_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \ + \ + if (!new_buffer) \ + { \ + _deque_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ + \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + new_buffer[j] = _deque_->buffer[i]; \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + \ + _deque_->alloc->free(_deque_->buffer); \ + \ + _deque_->buffer = new_buffer; \ + _deque_->capacity = capacity; \ + _deque_->front = 0; \ + _deque_->back = _deque_->count; \ + \ + success: \ + \ + if (_deque_->callbacks && _deque_->callbacks->resize) \ + _deque_->callbacks->resize(); \ + \ + return true; \ + } \ + \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \ + { \ + struct SNAME *result = \ + CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, \ + _deque_->alloc, _deque_->callbacks); \ + \ + if (!result) \ + { \ + _deque_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ + \ + if (_deque_->f_val->cpy) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + else \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + result->buffer[j] = _deque_->buffer[i]; \ + \ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + \ + result->count = _deque_->count; \ + result->front = 0; \ + result->back = _deque_->count; \ + \ + _deque_->flag = CMC_FLAG_OK; \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \ + { \ + _deque1_->flag = CMC_FLAG_OK; \ + _deque2_->flag = CMC_FLAG_OK; \ + \ + if (_deque1_->count != _deque2_->count) \ + return false; \ + \ + size_t i, j, k; \ + for (i = _deque1_->front, j = _deque2_->front, k = 0; \ + k < _deque1_->count; k++) \ + { \ + if (_deque1_->f_val->cmp(_deque1_->buffer[i], \ + _deque2_->buffer[j]) != 0) \ + return false; \ + \ + i = (i + 1) % _deque1_->capacity; \ + j = (j + 1) % _deque2_->capacity; \ + } \ + \ + return true; \ } #endif /* CMC_CMC_DEQUE_H */ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index d64dcaf..16b716a 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -220,8 +220,6 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ \ /* Iterator Functions */ \ /* Iterator Initialization */ \ @@ -860,36 +858,6 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " return true; \ } \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmap, \ - #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \ - m_->alloc, m_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ - { \ - 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; \ - } \ - } \ - \ - return true; \ - } \ - \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ { \ struct CMC_DEF_ITER(SNAME) iter; \ diff --git a/src/cor/core.h b/src/cor/core.h index 91e6460..375c597 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -32,6 +32,7 @@ #include "alloc.h" #include "callbacks.h" #include "flags.h" +#include "ftable.h" #define CMC__(A, B) A##B #define CMC_(A, B) CMC__(A, B) @@ -91,26 +92,4 @@ #define CMC_PARAM_K CMC_TUP_3 #define CMC_PARAM_V CMC_TUP_4 -/** - * A __VA_ARGS__ argument counter. This argument counter is slightly shifted: - * - * CMC_NARG(HELLO) -> 0 - * CMC_NARG(HELLO,) -> 1 - * CMC_NARG(HELLO, WORLD,) -> 2 - */ -#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N()) -#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__) -#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ - _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \ - _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ - _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ - _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ - _62, _63, N, ...) \ - N -#define CMC_SEQ_N() \ - 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \ - 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \ - 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 - #endif /* CMC_COR_CORE_H */ diff --git a/src/cor/ftable.h b/src/cor/ftable.h new file mode 100644 index 0000000..23c29a7 --- /dev/null +++ b/src/cor/ftable.h @@ -0,0 +1,28 @@ +/** + * ftable.h + * + * Creation Date: 27/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * Type definitions for Functions Tables. + */ + +#ifndef CMC_COR_FTABLE_H +#define CMC_COR_FTABLE_H + +/** + * Where T can either be K or V + */ +#define CMC_DEF_FTAB_CMP(T) int (*cmp)(T, T) +#define CMC_DEF_FTAB_CPY(T) T (*cpy)(T) +#define CMC_DEF_FTAB_STR(T) bool (*str)(FILE *, T) +#define CMC_DEF_FTAB_FREE(T) void (*free)(T) +#define CMC_DEF_FTAB_HASH(T) size_t (*hash)(T) +#define CMC_DEF_FTAB_PRI(T) int (*pri)(T, T) + +#endif /* CMC_COR_FTABLE_H */ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 9b91281..06cec26 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -8,24 +8,21 @@ * */ -/** - * Extensions to CMC - * - * - INIT - */ - #ifndef CMC_EXT_CMC_DEQUE_H #define CMC_EXT_CMC_DEQUE_H #include "../../cor/core.h" -#define CMC_EXT_CMC_DEQUE_PARTS INIT, +/** + * All the EXT parts of CMC Deque. + */ +#define CMC_EXT_CMC_DEQUE_PARTS INIT, ITER, STR /** * INIT * * The part 'INIT' gives a new way of initializing a collection. The collection - * struct is not heap allocated, only its internal structure (nodes, buffers) + * struct is not heap allocated, only its internal structure (nodes, buffers). */ #define CMC_EXT_CMC_DEQUE_INIT(BODY) \ CMC_EXT_CMC_DEQUE_INIT_HEADER(BODY) \ @@ -79,7 +76,7 @@ _deque_.count = 0; \ _deque_.front = 0; \ _deque_.back = 0; \ - _deque_.flag = cmc_flags.OK; \ + _deque_.flag = CMC_FLAG_OK; \ _deque_.f_val = f_val; \ _deque_.alloc = alloc; \ _deque_.callbacks = callbacks; \ @@ -87,4 +84,334 @@ return _deque_; \ } +/** + * ITER + */ +#define CMC_EXT_CMC_DEQUE_ITER(BODY) \ + CMC_EXT_CMC_DEQUE_ITER_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_ITER_SOURCE(BODY) + +#define CMC_EXT_CMC_DEQUE_ITER_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_ITER_SOURCE(BODY) \ + CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \ + /* Deque Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target deque */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_DEQUE_ITER_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = target->front; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + if (iter.target->back == 0) \ + iter.cursor = iter.target->capacity - 1; \ + else \ + iter.cursor = iter.target->back - 1; \ + \ + iter.index = iter.target->count - 1; \ + } \ + else \ + { \ + iter.cursor = 0; \ + iter.index = 0; \ + } \ + \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->front; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = false; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + if (iter->target->back == 0) \ + iter->cursor = iter->target->capacity - 1; \ + else \ + iter->cursor = iter->target->back - 1; \ + \ + iter->index = iter->target->count - 1; \ + \ + iter->start = false; \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ + iter->index++; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \ + : iter->cursor - 1; \ + iter->index--; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->index += steps; \ + iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->index -= steps; \ + \ + /* Prevent underflow */ \ + if (iter->cursor < steps) \ + iter->cursor += iter->target->capacity; \ + \ + iter->cursor -= steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor]; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->target->buffer[iter->cursor]); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_DEQUE_STR(BODY) \ + CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY) + +#define CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \ + CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY) \ + CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \ + { \ + struct SNAME *d_ = _deque_; \ + \ + return 0 <= fprintf(fptr, cmc_cmc_string_fmt_deque, \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, \ + d_->buffer, d_->capacity, d_->count, d_->front, \ + d_->back, d_->flag, d_->f_val, d_->alloc, \ + d_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \ + return false; \ + \ + i = (i + 1) % _deque_->capacity; \ + \ + if (j + 1 < _deque_->count) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + #endif /* CMC_EXT_CMC_DEQUE_H */ diff --git a/src/ext/cmc/hashbidimap.h b/src/ext/cmc/hashbidimap.h index aa2cfa5..c3cd76a 100644 --- a/src/ext/cmc/hashbidimap.h +++ b/src/ext/cmc/hashbidimap.h @@ -7,3 +7,15 @@ * Leonardo Vencovsky (https://github.com/LeoVen) * */ + +#ifndef CMC_EXT_CMC_HASHBIDIMAP_H +#define CMC_EXT_CMC_HASHBIDIMAP_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC HashBidiMap. + */ +#define CMC_EXT_CMC_HASHBIDIMAP_PARTS + +#endif /* CMC_EXT_CMC_HASHBIDIMAP_H */ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 48e1987..9c462ae 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -8,18 +8,15 @@ * */ -/** - * Extensions to CMC - * - * - INIT - */ - #ifndef CMC_EXT_CMC_HASHMAP_H #define CMC_EXT_CMC_HASHMAP_H #include "../../cor/core.h" -#define CMC_EXT_CMC_HASHMAP_PARTS INIT, ITER +/** + * All the EXT parts of CMC HashMap. + */ +#define CMC_EXT_CMC_HASHMAP_PARTS INIT, STR /** * INIT @@ -91,7 +88,7 @@ _map_.count = 0; \ _map_.capacity = real_capacity; \ _map_.load = load; \ - _map_.flag = cmc_flags.OK; \ + _map_.flag = CMC_FLAG_OK; \ _map_.f_key = f_key; \ _map_.f_val = f_val; \ _map_.alloc = alloc; \ @@ -100,4 +97,79 @@ return _map_; \ } +/** + * STR + * + * The part 'STR' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#define CMC_EXT_CMC_HASHMAP_STR(BODY) \ + 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_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_HEADER_(PFX, SNAME, V) \ + \ + struct cmc_string 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) + +#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; \ + } + #endif /* CMC_EXT_CMC_HASHMAP_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 35c7b5b..51495da 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -11,6 +11,7 @@ #ifndef CMC_MACRO_COLLECTIONS_H #define CMC_MACRO_COLLECTIONS_H +// clang-format off #include "cmc/bitset.h" /* Added in 30/04/2020 */ #include "cmc/deque.h" /* Added in 20/03/2019 */ #include "cmc/hashbidimap.h" /* Added in 26/09/2019 */ @@ -27,13 +28,18 @@ #include "cmc/stack.h" /* Added in 14/02/2019 */ #include "cmc/treemap.h" /* Added in 28/03/2019 */ #include "cmc/treeset.h" /* Added in 27/03/2019 */ + #include "cor/alloc.h" /* Added in 24/05/2020 */ #include "cor/bitset.h" /* Added in 20/05/2020 */ #include "cor/callbacks.h" /* Added in 24/05/2020 */ #include "cor/core.h" /* Added in 17/03/2020 */ #include "cor/flags.h" /* Added in 14/05/2020 */ +#include "cor/ftable.h" /* Added in 27/05/2020 */ #include "cor/hashtable.h" /* Added in 17/03/2020 */ + #include "ext/cmc/deque.h" /* Added in 25/05/2020 */ +#include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ + #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ #include "utl/futils.h" /* Added in 15/04/2020 */ @@ -42,6 +48,7 @@ #include "utl/test.h" /* Added in 26/06/2019 */ #include "utl/thread.h" /* Added in 14/05/2020 */ #include "utl/timer.h" /* Added in 12/04/2019 */ +// clang-format on /** * Generate a specific part of a collection @@ -72,6 +79,28 @@ #define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \ CMC_EXT_##LIB##_##COLLECTION##_PARTS +/** + * A __VA_ARGS__ argument counter. This argument counter is slightly shifted: + * + * CMC_NARG(HELLO) -> 0 + * CMC_NARG(HELLO,) -> 1 + * CMC_NARG(HELLO, WORLD,) -> 2 + */ +#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N()) +#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__) +#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ + _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \ + _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ + _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ + _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ + _62, _63, N, ...) \ + N +#define CMC_SEQ_N() \ + 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \ + 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \ + 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 + #define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \ CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \ (LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) From e39d60ade902b9185ef4a69bc86984405052e600 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 27 May 2020 01:19:58 -0300 Subject: [PATCH 09/51] Moving components to ext and updating tests/to_string.c for reference --- src/cmc/deque.h | 12 -- src/cmc/hashmap.h | 16 --- src/ext/cmc/deque.h | 13 +++ src/ext/cmc/hashmap.h | 246 ++++++++++++++++++++++------------------ src/macro_collections.h | 2 +- tests/to_string.c | 109 ++++++------------ 6 files changed, 183 insertions(+), 215 deletions(-) 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 From 89254ab5db45eda00553dc21fd3139426cbc44c4 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 29 May 2020 20:19:47 -0300 Subject: [PATCH 10/51] Started migrating things to EXT --- src/cmc/hashmap.h | 579 +++++++----------------------- src/cmc/hashmultimap.h | 649 +++++++--------------------------- src/ext/cmc/deque.h | 1 + src/ext/cmc/hashmap.h | 337 +++++++++++++++++- src/ext/cmc/hashmultimap.h | 472 +++++++++++++++++++++++++ src/macro_collections.h | 67 ++-- tests/main/src/deque.c | 21 -- tests/main/src/hashmap.c | 26 -- tests/main/src/hashmultimap.c | 27 -- tests/main/unt/utl.c | 9 + tests/to_string.c | 14 +- 11 files changed, 1131 insertions(+), 1071 deletions(-) create mode 100644 src/ext/cmc/hashmultimap.h diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 2127ab8..ad25ae0 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -47,187 +47,138 @@ /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \ - \ - /* Hashmap Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of keys */ \ - size_t count; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Hashmap Entry */ \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry Key */ \ - K key; \ - \ - /* Entry Value */ \ - V value; \ - \ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ - \ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; \ - \ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - int (*cmp)(K, K); \ - \ - /* Copy function */ \ - K (*cpy)(K); \ - \ - /* To string function */ \ - bool (*str)(FILE *, K); \ - \ - /* Free from memory function */ \ - void (*free)(K); \ - \ - /* Hash function */ \ - size_t (*hash)(K); \ - \ - /* Priority function */ \ - int (*pri)(K, K); \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Hashmap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target hashmap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_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); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - void CMC_(PFX, _release)(struct SNAME _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ - V * old_value); \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - bool CMC_(PFX, _full)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ - double CMC_(PFX, _load)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \ + \ + /* Hashmap Structure */ \ + struct SNAME \ + { \ + /* Array of Entries */ \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of keys */ \ + size_t count; \ + \ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Key function table */ \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Hashmap Entry */ \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry Key */ \ + K key; \ + \ + /* Entry Value */ \ + V value; \ + \ + /* The distance of this node to its original position, used by */ \ + /* robin-hood hashing */ \ + size_t dist; \ + \ + /* The sate of this node (DELETED, EMPTY, FILLED) */ \ + enum cmc_entry_state state; \ + }; \ + \ + /* Key struct function table */ \ + struct CMC_DEF_FKEY(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(K, K); \ + \ + /* Copy function */ \ + K (*cpy)(K); \ + \ + /* To string function */ \ + bool (*str)(FILE *, K); \ + \ + /* Free from memory function */ \ + void (*free)(K); \ + \ + /* Hash function */ \ + size_t (*hash)(K); \ + \ + /* Priority function */ \ + int (*pri)(K, K); \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_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); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ + void CMC_(PFX, _release)(struct SNAME _map_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ + V * old_value); \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + bool CMC_(PFX, _full)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ + double CMC_(PFX, _load)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); /* ------------------------------------------------------------------------- * Source @@ -842,272 +793,6 @@ return true; \ } \ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index++; \ - \ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index--; \ - \ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].key; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].value; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor].value); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ static struct CMC_DEF_ENTRY(SNAME) * \ CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ { \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index cc4461b..029bc8d 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -54,22 +54,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/hashtable.h" -/* ------------------------------------------------------------------------- - * HashMultiMap specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_hashmultimap = "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 HashMultiMap implementation */ @@ -90,194 +74,141 @@ static const char *cmc_cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ - \ - /* HashMultimap Structure */ \ - struct SNAME \ - { \ - /* Array of linked list to entries */ \ - struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of keys */ \ - size_t count; \ - \ - /* Load factor in range (0.0, infinity) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* HashMultimap Entry */ \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry Key */ \ - K key; \ - \ - /* Entry Value */ \ - V value; \ - \ - /* Next entry on the linked list */ \ - struct CMC_DEF_ENTRY(SNAME) * next; \ - \ - /* Previous entry on the linked list */ \ - struct CMC_DEF_ENTRY(SNAME) * prev; \ - }; \ - \ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - int (*cmp)(K, K); \ - \ - /* Copy function */ \ - K (*cpy)(K); \ - \ - /* To string function */ \ - bool (*str)(FILE *, K); \ - \ - /* Free from memory function */ \ - void (*free)(K); \ - \ - /* Hash function */ \ - size_t (*hash)(K); \ - \ - /* Priority function */ \ - int (*pri)(K, K); \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target hashmultimap */ \ - struct SNAME *target; \ - \ - /* Current entry */ \ - struct CMC_DEF_ENTRY(SNAME) * curr_entry; \ - \ - /* Cursor`s position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_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); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ - V * old_value); \ - size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, \ - V * *old_values); \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ - size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, \ - V * *out_values); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - bool CMC_(PFX, _full)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ - double CMC_(PFX, _load)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ + \ + /* HashMultimap Structure */ \ + struct SNAME \ + { \ + /* Array of linked list to entries */ \ + struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of keys */ \ + size_t count; \ + \ + /* Load factor in range (0.0, infinity) */ \ + double load; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Key function table */ \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* HashMultimap Entry */ \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry Key */ \ + K key; \ + \ + /* Entry Value */ \ + V value; \ + \ + /* Next entry on the linked list */ \ + struct CMC_DEF_ENTRY(SNAME) * next; \ + \ + /* Previous entry on the linked list */ \ + struct CMC_DEF_ENTRY(SNAME) * prev; \ + }; \ + \ + /* Key struct function table */ \ + struct CMC_DEF_FKEY(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(K, K); \ + \ + /* Copy function */ \ + K (*cpy)(K); \ + \ + /* To string function */ \ + bool (*str)(FILE *, K); \ + \ + /* Free from memory function */ \ + void (*free)(K); \ + \ + /* Hash function */ \ + size_t (*hash)(K); \ + \ + /* Priority function */ \ + int (*pri)(K, K); \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_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); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _map_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ + V * old_value); \ + size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, \ + V * *old_values); \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ + size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, \ + V * *out_values); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + bool CMC_(PFX, _full)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ + double CMC_(PFX, _load)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); /* ------------------------------------------------------------------------- * Source @@ -1111,316 +1042,6 @@ static const char *cmc_cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " return true; \ } \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ - \ - int n = snprintf( \ - str.s, cmc_string_len, cmc_cmc_string_fmt_hashmultimap, #SNAME, \ - #K, #V, m_, m_->buffer, m_->capacity, m_->count, m_->load, \ - m_->flag, m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ - \ - while (scan != NULL) \ - { \ - if (!_map_->f_key->str(fptr, scan->key) || \ - !_map_->f_val->str(fptr, scan->value)) \ - return false; \ - \ - scan = scan->next; \ - } \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.curr_entry = NULL; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i][0] != NULL) \ - { \ - iter.curr_entry = target->buffer[i][0]; \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1][1] != NULL) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.curr_entry = NULL; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i][0] != NULL) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1][1] != NULL) \ - { \ - iter.curr_entry = target->buffer[i - 1][1]; \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->curr_entry = iter->target->buffer[iter->first][0]; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->curr_entry = iter->target->buffer[iter->last][1]; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->curr_entry->next != NULL) \ - { \ - iter->curr_entry = iter->curr_entry->next; \ - iter->index++; \ - } \ - else \ - { \ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->cursor++; \ - \ - while (iter->target->buffer[iter->cursor][0] == NULL) \ - iter->cursor++; \ - \ - iter->curr_entry = iter->target->buffer[iter->cursor][0]; \ - \ - iter->index++; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->curr_entry->prev != NULL) \ - { \ - iter->curr_entry = iter->curr_entry->prev; \ - iter->index--; \ - } \ - else \ - { \ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->cursor--; \ - \ - while (iter->target->buffer[iter->cursor][1] == NULL) \ - iter->cursor--; \ - \ - iter->curr_entry = iter->target->buffer[iter->cursor][1]; \ - \ - iter->index--; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ - \ - return iter->curr_entry->key; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->curr_entry->value; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->curr_entry->value); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ struct CMC_DEF_ENTRY(SNAME) * \ CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ { \ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index b868dff..6b06766 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -113,6 +113,7 @@ static const char *cmc_cmc_string_fmt_deque = "struct %s<%s> " CMC_PARAM_V(BODY)) #define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \ + \ /* Deque Iterator */ \ struct CMC_DEF_ITER(SNAME) \ { \ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 76d679b..c21658a 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -16,7 +16,7 @@ /** * All the EXT parts of CMC HashMap. */ -#define CMC_EXT_CMC_HASHMAP_PARTS INIT, STR +#define CMC_EXT_CMC_HASHMAP_PARTS INIT, ITER, STR /* Used by STR */ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " @@ -112,6 +112,341 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " return _map_; \ } +/** + * ITER + */ +#define CMC_EXT_CMC_HASHMAP_ITER(BODY) \ + CMC_EXT_CMC_HASHMAP_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HASHMAP_ITER_SOURCE(BODY) + +#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE(BODY) \ + CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \ + \ + /* Hashmap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target hashmap */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* The index of the first element */ \ + size_t first; \ + \ + /* The index of the last element */ \ + size_t last; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.first; \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ + \ + iter->index++; \ + \ + while (1) \ + { \ + iter->cursor++; \ + scan = &(iter->target->buffer[iter->cursor]); \ + \ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ + \ + iter->index--; \ + \ + while (1) \ + { \ + iter->cursor--; \ + scan = &(iter->target->buffer[iter->cursor]); \ + \ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (K){ 0 }; \ + \ + return iter->target->buffer[iter->cursor].key; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor].value; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->target->buffer[iter->cursor].value); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + /** * STR * diff --git a/src/ext/cmc/hashmultimap.h b/src/ext/cmc/hashmultimap.h new file mode 100644 index 0000000..9a38aab --- /dev/null +++ b/src/ext/cmc/hashmultimap.h @@ -0,0 +1,472 @@ +/** + * hashmultimap.h + * + * Creation Date: 29/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_HASHMULTIMAP_H +#define CMC_EXT_CMC_HASHMULTIMAP_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC HashMultiMap. + */ +#define CMC_EXT_CMC_HASHMULTIMAP_PARTS ITER, STR + +/* Used by STR */ +static const char *cmc_cmc_string_fmt_hashmultimap = "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 }"; + +/** + * ITER + */ +#define CMC_EXT_CMC_HASHMULTIMAP_ITER(BODY) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(BODY) + +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(BODY) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \ + \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target hashmultimap */ \ + struct SNAME *target; \ + \ + /* Current entry */ \ + struct CMC_DEF_ENTRY(SNAME) * curr_entry; \ + \ + /* Cursor`s position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* The index of the first element */ \ + size_t first; \ + \ + /* The index of the last element */ \ + size_t last; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.curr_entry = NULL; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ + \ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter.curr_entry = target->buffer[i][0]; \ + iter.first = i; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.first; \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \ + \ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.curr_entry = NULL; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ + \ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \ + \ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter.curr_entry = target->buffer[i - 1][1]; \ + iter.last = i - 1; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + iter->curr_entry = iter->target->buffer[iter->first][0]; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + iter->curr_entry = iter->target->buffer[iter->last][1]; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->curr_entry->next != NULL) \ + { \ + iter->curr_entry = iter->curr_entry->next; \ + iter->index++; \ + } \ + else \ + { \ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->cursor++; \ + \ + while (iter->target->buffer[iter->cursor][0] == NULL) \ + iter->cursor++; \ + \ + iter->curr_entry = iter->target->buffer[iter->cursor][0]; \ + \ + iter->index++; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->curr_entry->prev != NULL) \ + { \ + iter->curr_entry = iter->curr_entry->prev; \ + iter->index--; \ + } \ + else \ + { \ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->cursor--; \ + \ + while (iter->target->buffer[iter->cursor][1] == NULL) \ + iter->cursor--; \ + \ + iter->curr_entry = iter->target->buffer[iter->cursor][1]; \ + \ + iter->index--; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (K){ 0 }; \ + \ + return iter->curr_entry->key; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->curr_entry->value; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->curr_entry->value); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_HASHMULTIMAP_STR(BODY) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(BODY) + +#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(BODY) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(PFX, SNAME, K, V) \ + \ + 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 *key_val_sep); + +#define CMC_EXT_CMC_HASHMULTIMAP_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_hashmultimap, \ + 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--) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][1]; \ + \ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ + \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ + \ + while (scan != NULL) \ + { \ + if (!_map_->f_key->str(fptr, scan->key)) \ + return false; \ + \ + fprintf(fptr, "%s", key_val_sep); \ + \ + if (!_map_->f_val->str(fptr, scan->value)) \ + return false; \ + \ + scan = scan->next; \ + \ + if (i + 1 < last) \ + fprintf(fptr, "%s", separator); \ + } \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_HASHMULTIMAP_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 2364541..06fc4bd 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -12,42 +12,43 @@ #define CMC_MACRO_COLLECTIONS_H // clang-format off -#include "cmc/bitset.h" /* Added in 30/04/2020 */ -#include "cmc/deque.h" /* Added in 20/03/2019 */ -#include "cmc/hashbidimap.h" /* Added in 26/09/2019 */ -#include "cmc/hashmap.h" /* Added in 03/04/2019 */ -#include "cmc/hashmultimap.h" /* Added in 26/04/2019 */ -#include "cmc/hashmultiset.h" /* Added in 10/04/2019 */ -#include "cmc/hashset.h" /* Added in 01/04/2019 */ -#include "cmc/heap.h" /* Added in 25/03/2019 */ -#include "cmc/intervalheap.h" /* Added in 06/07/2019 */ -#include "cmc/linkedlist.h" /* Added in 22/03/2019 */ -#include "cmc/list.h" /* Added in 12/02/2019 */ -#include "cmc/queue.h" /* Added in 15/02/2019 */ -#include "cmc/sortedlist.h" /* Added in 17/09/2019 */ -#include "cmc/stack.h" /* Added in 14/02/2019 */ -#include "cmc/treemap.h" /* Added in 28/03/2019 */ -#include "cmc/treeset.h" /* Added in 27/03/2019 */ +#include "cmc/bitset.h" /* Added in 30/04/2020 */ +#include "cmc/deque.h" /* Added in 20/03/2019 */ +#include "cmc/hashbidimap.h" /* Added in 26/09/2019 */ +#include "cmc/hashmap.h" /* Added in 03/04/2019 */ +#include "cmc/hashmultimap.h" /* Added in 26/04/2019 */ +#include "cmc/hashmultiset.h" /* Added in 10/04/2019 */ +#include "cmc/hashset.h" /* Added in 01/04/2019 */ +#include "cmc/heap.h" /* Added in 25/03/2019 */ +#include "cmc/intervalheap.h" /* Added in 06/07/2019 */ +#include "cmc/linkedlist.h" /* Added in 22/03/2019 */ +#include "cmc/list.h" /* Added in 12/02/2019 */ +#include "cmc/queue.h" /* Added in 15/02/2019 */ +#include "cmc/sortedlist.h" /* Added in 17/09/2019 */ +#include "cmc/stack.h" /* Added in 14/02/2019 */ +#include "cmc/treemap.h" /* Added in 28/03/2019 */ +#include "cmc/treeset.h" /* Added in 27/03/2019 */ -#include "cor/alloc.h" /* Added in 24/05/2020 */ -#include "cor/bitset.h" /* Added in 20/05/2020 */ -#include "cor/callbacks.h" /* Added in 24/05/2020 */ -#include "cor/core.h" /* Added in 17/03/2020 */ -#include "cor/flags.h" /* Added in 14/05/2020 */ -#include "cor/ftable.h" /* Added in 27/05/2020 */ -#include "cor/hashtable.h" /* Added in 17/03/2020 */ +#include "cor/alloc.h" /* Added in 24/05/2020 */ +#include "cor/bitset.h" /* Added in 20/05/2020 */ +#include "cor/callbacks.h" /* Added in 24/05/2020 */ +#include "cor/core.h" /* Added in 17/03/2020 */ +#include "cor/flags.h" /* Added in 14/05/2020 */ +#include "cor/ftable.h" /* Added in 27/05/2020 */ +#include "cor/hashtable.h" /* Added in 17/03/2020 */ -#include "ext/cmc/deque.h" /* Added in 25/05/2020 */ -#include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ +#include "ext/cmc/deque.h" /* Added in 25/05/2020 */ +#include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ +#include "ext/cmc/hashmultimap.h" /* Added in 29/05/2020 */ -#include "utl/assert.h" /* Added in 27/06/2019 */ -#include "utl/foreach.h" /* Added in 25/02/2019 */ -#include "utl/futils.h" /* Added in 15/04/2020 */ -#include "utl/log.h" /* Added in 21/06/2019 */ -#include "utl/mutex.h" /* Added in 14/05/2020 */ -#include "utl/test.h" /* Added in 26/06/2019 */ -#include "utl/thread.h" /* Added in 14/05/2020 */ -#include "utl/timer.h" /* Added in 12/04/2019 */ +#include "utl/assert.h" /* Added in 27/06/2019 */ +#include "utl/foreach.h" /* Added in 25/02/2019 */ +#include "utl/futils.h" /* Added in 15/04/2020 */ +#include "utl/log.h" /* Added in 21/06/2019 */ +#include "utl/mutex.h" /* Added in 14/05/2020 */ +#include "utl/test.h" /* Added in 26/06/2019 */ +#include "utl/thread.h" /* Added in 14/05/2020 */ +#include "utl/timer.h" /* Added in 12/04/2019 */ // clang-format on /** diff --git a/tests/main/src/deque.c b/tests/main/src/deque.c index 00c5992..ef319b7 100644 --- a/tests/main/src/deque.c +++ b/tests/main/src/deque.c @@ -361,27 +361,6 @@ _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_) } return 1; } -struct cmc_string d_to_string(struct deque *_deque_) -{ - struct cmc_string str; - struct deque *d_ = _deque_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_deque, - "CMC_PARAM_SNAME((d, deque, , , size_t))", - "CMC_PARAM_V((d, deque, , , size_t))", d_, d_->buffer, - d_->capacity, d_->count, d_->front, d_->back, d_->flag, - d_->f_val, d_->alloc, d_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool d_print(struct deque *_deque_, FILE *fptr) -{ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) - return 0; - i = (i + 1) % _deque_->capacity; - } - return 1; -} struct deque_iter d_iter_start(struct deque *target) { struct deque_iter iter; diff --git a/tests/main/src/hashmap.c b/tests/main/src/hashmap.c index 11c6b46..63ccc60 100644 --- a/tests/main/src/hashmap.c +++ b/tests/main/src/hashmap.c @@ -552,32 +552,6 @@ _Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_) } return 1; } -struct cmc_string hm_to_string(struct hashmap *_map_) -{ - struct cmc_string str; - struct hashmap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmap, - "CMC_PARAM_SNAME((hm, hashmap, , size_t, size_t))", - "CMC_PARAM_K((hm, hashmap, , size_t, size_t))", - "CMC_PARAM_V((hm, hashmap, , size_t, size_t))", m_, - m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, m_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool hm_print(struct hashmap *_map_, FILE *fptr) -{ - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmap_entry *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 0; - } - } - return 1; -} struct hashmap_iter hm_iter_start(struct hashmap *target) { struct hashmap_iter iter; diff --git a/tests/main/src/hashmultimap.c b/tests/main/src/hashmultimap.c index ae280f9..dd64884 100644 --- a/tests/main/src/hashmultimap.c +++ b/tests/main/src/hashmultimap.c @@ -720,33 +720,6 @@ _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_) } return 1; } -struct cmc_string hmm_to_string(struct hashmultimap *_map_) -{ - struct cmc_string str; - struct hashmultimap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmultimap, - "CMC_PARAM_SNAME((hmm, hashmultimap, , size_t, size_t))", - "CMC_PARAM_K((hmm, hashmultimap, , size_t, size_t))", - "CMC_PARAM_V((hmm, hashmultimap, , size_t, size_t))", m_, - m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, m_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr) -{ - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan != ((void *)0)) - { - if (!_map_->f_key->str(fptr, scan->key) || - !_map_->f_val->str(fptr, scan->value)) - return 0; - scan = scan->next; - } - } - return 1; -} struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) { struct hashmultimap_iter iter; diff --git a/tests/main/unt/utl.c b/tests/main/unt/utl.c index 84cc860..44376a7 100644 --- a/tests/main/unt/utl.c +++ b/tests/main/unt/utl.c @@ -2,6 +2,15 @@ #ifndef CMC_UNIT_TEST_UTL__ #define CMC_UNIT_TEST_UTL__ +/** + * TEMPORARY + */ +struct cmc_string +{ + char s[400]; +}; +static const size_t cmc_string_len = 400; + #include #include #include diff --git a/tests/to_string.c b/tests/to_string.c index 5794037..18acdde 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -3,8 +3,9 @@ #include "macro_collections.h" // clang-format off -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int)) struct { @@ -21,16 +22,22 @@ int main(void) 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); + struct hashmultimap *hmm = hmm_new(100, 0.6, + (struct hashmultimap_fkey *)&int_ftab, + (struct hashmultimap_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); hm_to_string(hm, stdout); hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hmm_to_string(hmm, stdout); + hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); for (int i = 0; i < 20; i++) { d_push_back(d, i); hm_insert(hm, i, i); + hmm_insert(hmm, i, i); } fprintf(stdout, "\n"); @@ -39,9 +46,12 @@ int main(void) d_print(d, stdout, "\n[ ", ", ", " ]\n"); hm_to_string(hm, stdout); hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hmm_to_string(hmm, stdout); + hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); d_free(d); hm_free(hm); + hmm_free(hmm); } // clang-format on From b85f3d1f81630bfd8c4d77792604021067335442 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sat, 30 May 2020 00:05:46 -0300 Subject: [PATCH 11/51] Some refactoring and moving more stuff to EXT --- src/cmc/hashbidimap.h | 8 +- src/cmc/hashmultiset.h | 356 +-------------------------- src/ext/cmc/hashmap.h | 2 +- src/ext/cmc/hashmultimap.h | 1 + src/ext/cmc/hashmultiset.h | 437 ++++++++++++++++++++++++++++++++++ src/ext/cmc/hashset.h | 21 ++ src/macro_collections.h | 1 + tests/main/src/hashmultiset.c | 24 -- tests/to_string.c | 14 +- 9 files changed, 477 insertions(+), 387 deletions(-) create mode 100644 src/ext/cmc/hashmultiset.h create mode 100644 src/ext/cmc/hashset.h diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index 00006d6..00dd671 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -1049,9 +1049,9 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " { \ for (size_t i = 0; i < target->capacity; i++) \ { \ - struct CMC_DEF_ENTRY(SNAME) *tmp = target->buffer[i][0]; \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ \ - if (tmp != NULL && tmp != CMC_ENTRY_DELETED) \ + if (entry && entry != CMC_ENTRY_DELETED) \ { \ iter->first = i; \ break; \ @@ -1062,9 +1062,9 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ for (size_t i = target->capacity; i > 0; i--) \ { \ - struct CMC_DEF_ENTRY(SNAME) *tmp = target->buffer[i - 1][0]; \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][0]; \ \ - if (tmp != NULL && tmp != CMC_ENTRY_DELETED) \ + if (entry && entry != CMC_ENTRY_DELETED) \ { \ iter->last = i - 1; \ break; \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index b2c5613..e816b57 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -36,23 +36,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/hashtable.h" -/* ------------------------------------------------------------------------- - * HashMultiSet specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_hashmultiset = - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "cardinality:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core HashMultiSet implementation */ @@ -142,31 +125,6 @@ static const char *cmc_cmc_string_fmt_hashmultiset = int (*pri)(V, V); \ }; \ \ - /* HashMultiset Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target HashMultiset */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ @@ -204,8 +162,6 @@ static const char *cmc_cmc_string_fmt_hashmultiset = bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \ \ /* Set Operations */ \ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ @@ -226,30 +182,7 @@ static const char *cmc_cmc_string_fmt_hashmultiset = bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ struct SNAME * _set2_); \ bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source @@ -877,35 +810,6 @@ static const char *cmc_cmc_string_fmt_hashmultiset = return true; \ } \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \ - { \ - struct cmc_string str; \ - struct SNAME *s_ = _set_; \ - \ - int n = snprintf( \ - str.s, cmc_string_len, cmc_cmc_string_fmt_hashmultiset, #SNAME, \ - #V, s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, \ - s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_set_->f_val->str(fptr, entry->value)) \ - return false; \ - } \ - } \ - \ - return true; \ - } \ - \ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ struct SNAME * _set2_) \ { \ @@ -1182,264 +1086,6 @@ static const char *cmc_cmc_string_fmt_hashmultiset = return true; \ } \ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index++; \ - \ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index--; \ - \ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].value; \ - } \ - \ - size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return 0; \ - \ - return iter->target->buffer[iter->cursor].multiplicity; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, \ V value) \ { \ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index c21658a..8ae193c 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -131,7 +131,7 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " #define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \ \ - /* Hashmap Iterator */ \ + /* HashMap Iterator */ \ struct CMC_DEF_ITER(SNAME) \ { \ /* Target hashmap */ \ diff --git a/src/ext/cmc/hashmultimap.h b/src/ext/cmc/hashmultimap.h index 9a38aab..fdaa9e3 100644 --- a/src/ext/cmc/hashmultimap.h +++ b/src/ext/cmc/hashmultimap.h @@ -50,6 +50,7 @@ static const char *cmc_cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " #define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \ \ + /* HashMultiMap Iterator */ \ struct CMC_DEF_ITER(SNAME) \ { \ /* Target hashmultimap */ \ diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h new file mode 100644 index 0000000..a55617b --- /dev/null +++ b/src/ext/cmc/hashmultiset.h @@ -0,0 +1,437 @@ +/** + * hashmultiset.h + * + * Creation Date: 30/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_HASHMULTISET_H +#define CMC_EXT_CMC_HASHMULTISET_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC HashMultiSet. + */ +#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, STR + +/* Used by STR */ +static const char *cmc_cmc_string_fmt_hashmultiset = + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "cardinality:%" PRIuMAX ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; + +/** + * ITER + */ +#define CMC_EXT_CMC_HASHMULTISET_ITER(BODY) \ + CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(BODY) + +#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(BODY) \ + CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* HashMultiSet Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target HashMultiset */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* The index of the first element */ \ + size_t first; \ + \ + /* The index of the last element */ \ + size_t last; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.first; \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ + \ + iter->index++; \ + \ + while (1) \ + { \ + iter->cursor++; \ + scan = &(iter->target->buffer[iter->cursor]); \ + \ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ + \ + iter->index--; \ + \ + while (1) \ + { \ + iter->cursor--; \ + scan = &(iter->target->buffer[iter->cursor]); \ + \ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor].value; \ + } \ + \ + size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return 0; \ + \ + return iter->target->buffer[iter->cursor].multiplicity; \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * STR + * + * The part 'STR' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#define CMC_EXT_CMC_HASHMULTISET_STR(BODY) \ + CMC_EXT_CMC_HASHMULTISET_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(BODY) + +#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHMULTISET_STR_HEADER_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(BODY) \ + CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_( \ + CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end, const char *key_val_sep); + +#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ + { \ + struct SNAME *s_ = _set_; \ + \ + return 0 <= fprintf(fptr, cmc_cmc_string_fmt_hashmultiset, \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, \ + s_->buffer, s_->capacity, s_->count, \ + s_->cardinality, s_->load, s_->flag, s_->f_val, \ + s_->alloc, s_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end, const char *val_mul_sep) \ + { \ + fprintf(fptr, "%s", start); \ + \ + size_t last = 0; \ + for (size_t i = _set_->capacity; i > 0; i--) \ + { \ + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ + \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ + \ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (!_set_->f_val->str(fptr, entry->value)) \ + return false; \ + \ + fprintf(fptr, "%s", val_mul_sep); \ + \ + if (fprintf(fptr, "%" PRIuMAX "", entry->multiplicity) < 0) \ + return false; \ + \ + if (i + 1 < last) \ + fprintf(fptr, "%s", separator); \ + } \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_HASHMULTISET_H */ diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h new file mode 100644 index 0000000..fab2d76 --- /dev/null +++ b/src/ext/cmc/hashset.h @@ -0,0 +1,21 @@ +/** + * hashset.h + * + * Creation Date: 29/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_HASHSET_H +#define CMC_EXT_CMC_HASHSET_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC HashSet. + */ +#define CMC_EXT_CMC_HASHSET_PARTS + +#endif /* CMC_EXT_CMC_HASHSET_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 06fc4bd..31ec322 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -40,6 +40,7 @@ #include "ext/cmc/deque.h" /* Added in 25/05/2020 */ #include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ #include "ext/cmc/hashmultimap.h" /* Added in 29/05/2020 */ +#include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/main/src/hashmultiset.c b/tests/main/src/hashmultiset.c index 1da5571..579799a 100644 --- a/tests/main/src/hashmultiset.c +++ b/tests/main/src/hashmultiset.c @@ -553,30 +553,6 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) } return 1; } -struct cmc_string hms_to_string(struct hashmultiset *_set_) -{ - struct cmc_string str; - struct hashmultiset *s_ = _set_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashmultiset, - "CMC_PARAM_SNAME((hms, hashmultiset, , , size_t))", - "CMC_PARAM_V((hms, hashmultiset, , , size_t))", s_, - s_->buffer, s_->capacity, s_->count, s_->cardinality, - s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool hms_print(struct hashmultiset *_set_, FILE *fptr) -{ - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (!_set_->f_val->str(fptr, entry->value)) - return 0; - } - } - return 1; -} struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { diff --git a/tests/to_string.c b/tests/to_string.c index 18acdde..2b59500 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -3,9 +3,10 @@ #include "macro_collections.h" // clang-format off -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int)) struct { @@ -22,9 +23,10 @@ int main(void) 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); - struct hashmultimap *hmm = hmm_new(100, 0.6, + struct hashmultimap *hmm = hmm_new(100, 0.8, (struct hashmultimap_fkey *)&int_ftab, (struct hashmultimap_fval *)&int_ftab); + struct hashmultiset *hms = hms_new(100, 0.6, (struct hashmultiset_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -32,12 +34,15 @@ int main(void) hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hmm_to_string(hmm, stdout); hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hms_to_string(hms, stdout); + hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); for (int i = 0; i < 20; i++) { d_push_back(d, i); hm_insert(hm, i, i); hmm_insert(hmm, i, i); + hms_insert(hms, i); } fprintf(stdout, "\n"); @@ -48,10 +53,13 @@ int main(void) hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hmm_to_string(hmm, stdout); hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hms_to_string(hms, stdout); + hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); d_free(d); hm_free(hm); hmm_free(hmm); + hms_free(hms); } // clang-format on From 624d1613f0bfee28d1ee5b0a753935865b9f22e7 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sun, 31 May 2020 00:50:55 -0300 Subject: [PATCH 12/51] Adding and fixing things, documenting code and moving more stuff to EXT --- src/cmc/hashset.h | 320 +---------------------------- src/cor/core.h | 2 +- src/ext/cmc/hashmap.h | 3 - src/ext/cmc/hashmultiset.h | 3 - src/ext/cmc/hashset.h | 398 ++++++++++++++++++++++++++++++++++++- src/macro_collections.h | 107 +++++++++- tests/main/src/hashset.c | 24 --- tests/to_string.c | 12 +- 8 files changed, 514 insertions(+), 355 deletions(-) diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 1cbf3c0..7e6ae1d 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -29,21 +29,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/hashtable.h" -/* ------------------------------------------------------------------------- - * HashSet specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p }"; - /** * Core HashSet implementation */ @@ -183,8 +168,6 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \ \ /* Set Operations */ \ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ @@ -203,29 +186,7 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ struct SNAME * _set2_); \ bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source @@ -737,35 +698,6 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \ - { \ - struct cmc_string str; \ - struct SNAME *s_ = _set_; \ - \ - int n = \ - snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashset, \ - #SNAME, #V, s_, s_->buffer, s_->capacity, s_->count, \ - s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_set_->f_val->str(fptr, entry->value)) \ - return false; \ - } \ - } \ - \ - return true; \ - } \ - \ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ struct SNAME * _set2_) \ { \ @@ -1020,256 +952,6 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " return true; \ } \ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index++; \ - \ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index--; \ - \ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].value; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ static struct CMC_DEF_ENTRY(SNAME) * \ CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ { \ diff --git a/src/cor/core.h b/src/cor/core.h index 375c597..2a6979f 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -84,7 +84,7 @@ * K - Key type * V - Value type * - * PARAM := (PFX, SNAME, SIZE, K, V) + * PARAMS := (PFX, SNAME, SIZE, K, V) */ #define CMC_PARAM_PFX CMC_TUP_0 #define CMC_PARAM_SNAME CMC_TUP_1 diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 8ae193c..46f0149 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -449,9 +449,6 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " /** * STR - * - * The part 'STR' gives a new way of initializing a collection. The collection - * struct is not heap allocated, only its internal structure (nodes, buffers). */ #define CMC_EXT_CMC_HASHMAP_STR(BODY) \ CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \ diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h index a55617b..975b868 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext/cmc/hashmultiset.h @@ -358,9 +358,6 @@ static const char *cmc_cmc_string_fmt_hashmultiset = /** * STR - * - * The part 'STR' gives a new way of initializing a collection. The collection - * struct is not heap allocated, only its internal structure (nodes, buffers). */ #define CMC_EXT_CMC_HASHMULTISET_STR(BODY) \ CMC_EXT_CMC_HASHMULTISET_STR_HEADER(BODY) \ diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h index fab2d76..d53d06a 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext/cmc/hashset.h @@ -16,6 +16,402 @@ /** * All the EXT parts of CMC HashSet. */ -#define CMC_EXT_CMC_HASHSET_PARTS +#define CMC_EXT_CMC_HASHSET_PARTS ITER, STR + +/* Used by STR */ +static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p }"; + +/** + * ITER + */ +#define CMC_EXT_CMC_HASHSET_ITER(BODY) \ + CMC_EXT_CMC_HASHSET_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HASHSET_ITER_SOURCE(BODY) + +#define CMC_EXT_CMC_HASHSET_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHSET_ITER_SOURCE(BODY) \ + CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHSET_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* HashSet Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target HashSet */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* The index of the first element */ \ + size_t first; \ + \ + /* The index of the last element */ \ + size_t last; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_HASHSET_ITER_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.first; \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ + \ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + \ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ + \ + iter->index++; \ + \ + while (1) \ + { \ + iter->cursor++; \ + scan = &(iter->target->buffer[iter->cursor]); \ + \ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + struct CMC_DEF_ENTRY(SNAME) *scan = \ + &(iter->target->buffer[iter->cursor]); \ + \ + iter->index--; \ + \ + while (1) \ + { \ + iter->cursor--; \ + scan = &(iter->target->buffer[iter->cursor]); \ + \ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor].value; \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_HASHSET_STR(BODY) \ + CMC_EXT_CMC_HASHSET_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHSET_STR_SOURCE(BODY) + +#define CMC_EXT_CMC_HASHSET_STR_HEADER(BODY) \ + CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHSET_STR_SOURCE(BODY) \ + CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(BODY), \ + CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HASHSET_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_HASHSET_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ + { \ + struct SNAME *s_ = _set_; \ + \ + return 0 <= fprintf(fptr, cmc_cmc_string_fmt_hashset, \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, \ + s_->buffer, s_->capacity, s_->count, s_->load, \ + s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + size_t last = 0; \ + for (size_t i = _set_->capacity; i > 0; i--) \ + { \ + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ + \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ + \ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (!_set_->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_HASHSET_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 31ec322..237b580 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -8,6 +8,21 @@ * */ +/** + * This file provides everything from the C Macro Collections library. + * + * Every data structure and features are available through this header. There is + * also three macros that can help you generate whichever Collection you need + * from any given sub-library. They are: + * + * - C_MACRO_COLLECTIONS + * - C_MACRO_COLLECTIONS_GEN + * - C_MACRO_COLLECTIONS_GEN_HEADER + * - C_MACRO_COLLECTIONS_GEN_SOURCE + * - C_MACRO_COLLECTIONS_ALL + * - C_MACRO_COLLECTIONS_ALL_HEADER + * - C_MACRO_COLLECTIONS_ALL_SOURCE + */ #ifndef CMC_MACRO_COLLECTIONS_H #define CMC_MACRO_COLLECTIONS_H @@ -41,6 +56,7 @@ #include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ #include "ext/cmc/hashmultimap.h" /* Added in 29/05/2020 */ #include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */ +#include "ext/cmc/hashset.h" /* Added in 31/05/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ @@ -53,7 +69,15 @@ // clang-format on /** - * Generate a specific part of a collection + * C_MACRO_COLLECTIONS + * + * Generate a specific part of a specific collection from a specific library. + * + * \param LIB The collection's sub-library + * \param COLLECTION The name of the collection in all uppercase + * \param PART The part of the collection (either CORE or one available at EXT) + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ #define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE)(PARAMS) @@ -61,26 +85,102 @@ CMC_##LIB##_##COLLECTION##_##PART##_##FILE /** - * Generate everything provided by a collection included in ext + * C_MACRO_COLLECTIONS_GEN + * + * Generate the CORE of a collection along with one or more part from EXT. The + * headers are generated first, then the source code. + * + * \param LIB The collection's sub-library + * \param COLLECTION The name of the collection in all uppercase + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) + * \param PARTS A non-empty tuple of all desired EXT parts + */ +#define C_MACRO_COLLECTIONS_GEN(LIB, COLLECTION, PARAMS, PARTS) \ + C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \ + C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) + +/** + * C_MACRO_COLLECTIONS_GEN_HEADER + * + * Generate all headers of CORE and the specified header parts of a collection. + * + * \param LIB The collection's sub-library + * \param COLLECTION The name of the collection in all uppercase + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) + * \param PARTS A non-empty tuple of all desired EXT parts + */ +#define C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, CMC_EVAL PARTS) + +/** + * C_MACRO_COLLECTIONS_GEN_SOURCE + * + * Generate all sources of CORE and the specified source parts of a collection. + * + * \param LIB The collection's sub-library + * \param COLLECTION The name of the collection in all uppercase + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) + * \param PARTS A non-empty tuple of all desired EXT parts + */ +#define C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, CMC_EVAL PARTS) + +/** + * C_MACRO_COLLECTIONS_ALL + * + * Generate everything provided by a collection included in the EXT library. The + * headers are generated first, then the source code. + * + * \param LIB The collection's library + * \param COLLECTION The name of the collection in all uppercase + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V */ #define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \ C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \ C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) +/** + * C_MACRO_COLLECTIONS_ALL_HEADER + * + * Generates all headers (CORE and those at EXT) from a given collection. + * + * \param LIB The collection's library + * \param COLLECTION The name of the collection in all uppercase + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V + */ #define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, \ C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) +/** + * C_MACRO_COLLECTIONS_ALL_SOURCE + * + * Generates all sources (CORE and those at EXT) from a given collection. + * + * \param LIB The collection's library + * \param COLLECTION The name of the collection in all uppercase + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V + */ #define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, \ C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) -/* Gets the macro with all EXT parts of a collection */ +/** + * C_MACRO_COLLECTIONS_PARTS + * + * Gets the macro with all EXT parts of a collection. Every collection has this + * macro defined in the EXT libraries. + */ #define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \ CMC_EXT_##LIB##_##COLLECTION##_PARTS, +/* Evaluates a tuple so that (A, B) -> A, B, */ +#define CMC_EVAL(...) __VA_ARGS__, + /** * A __VA_ARGS__ argument counter. This argument counter is slightly shifted: * @@ -103,6 +203,7 @@ 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +/* Generates the FILE for each part (__VA_ARGS__) of a collection */ #define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \ CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \ (LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) diff --git a/tests/main/src/hashset.c b/tests/main/src/hashset.c index 4f39d25..94fb021 100644 --- a/tests/main/src/hashset.c +++ b/tests/main/src/hashset.c @@ -455,30 +455,6 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) } return 1; } -struct cmc_string hs_to_string(struct hashset *_set_) -{ - struct cmc_string str; - struct hashset *s_ = _set_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashset, - "CMC_PARAM_SNAME((hs, hashset, , , size_t))", - "CMC_PARAM_V((hs, hashset, , , size_t))", s_, s_->buffer, - s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, - s_->alloc, s_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool hs_print(struct hashset *_set_, FILE *fptr) -{ - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (!_set_->f_val->str(fptr, entry->value)) - return 0; - } - } - return 1; -} struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) { struct hashset *_set_r_ = diff --git a/tests/to_string.c b/tests/to_string.c index 2b59500..531bfb6 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -7,6 +7,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int)) struct { @@ -26,7 +27,10 @@ int main(void) struct hashmultimap *hmm = hmm_new(100, 0.8, (struct hashmultimap_fkey *)&int_ftab, (struct hashmultimap_fval *)&int_ftab); - struct hashmultiset *hms = hms_new(100, 0.6, (struct hashmultiset_fval *)&int_ftab); + struct hashmultiset *hms = hms_new(100, 0.6, + (struct hashmultiset_fval *)&int_ftab); + struct hashset *hs = hs_new(100, 0.6, + (struct hashset_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -36,6 +40,8 @@ int main(void) hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hms_to_string(hms, stdout); hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hs_to_string(hs, stdout); + hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); for (int i = 0; i < 20; i++) { @@ -43,6 +49,7 @@ int main(void) hm_insert(hm, i, i); hmm_insert(hmm, i, i); hms_insert(hms, i); + hs_insert(hs, i); } fprintf(stdout, "\n"); @@ -55,11 +62,14 @@ int main(void) hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hms_to_string(hms, stdout); hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hs_to_string(hs, stdout); + hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm); hmm_free(hmm); hms_free(hms); + hs_free(hs); } // clang-format on From ce4fadff01955fb516c3b20ea7ac55a2e4c8daf4 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sun, 31 May 2020 01:00:13 -0300 Subject: [PATCH 13/51] Hotfix --- src/cmc/hashset.h | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 7e6ae1d..4b21cd9 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -112,31 +112,6 @@ int (*pri)(V, V); \ }; \ \ - /* Hashset Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target Hashset */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ From 69eed7283851e13a1a33cbcd83f96660ebeaf920 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 1 Jun 2020 13:59:03 -0300 Subject: [PATCH 14/51] Adding the folder path to file names --- src/cmc/bitset.h | 2 +- src/cmc/deque.h | 2 +- src/cmc/hashbidimap.h | 2 +- src/cmc/hashmap.h | 2 +- src/cmc/hashmultimap.h | 2 +- src/cmc/hashmultiset.h | 2 +- src/cmc/hashset.h | 2 +- src/cmc/heap.h | 2 +- src/cmc/intervalheap.h | 2 +- src/cmc/linkedlist.h | 2 +- src/cmc/list.h | 2 +- src/cmc/queue.h | 2 +- src/cmc/sortedlist.h | 2 +- src/cmc/stack.h | 2 +- src/cmc/treemap.h | 2 +- src/cmc/treeset.h | 2 +- src/cor/alloc.h | 2 +- src/cor/bitset.h | 2 +- src/cor/callbacks.h | 2 +- src/cor/core.h | 2 +- src/cor/flags.h | 2 +- src/cor/ftable.h | 2 +- src/cor/hashtable.h | 2 +- src/ext/cmc/deque.h | 2 +- src/ext/cmc/hashbidimap.h | 2 +- src/ext/cmc/hashmap.h | 2 +- src/ext/cmc/hashmultimap.h | 2 +- src/ext/cmc/hashmultiset.h | 2 +- src/ext/cmc/hashset.h | 2 +- src/utl/assert.h | 2 +- src/utl/foreach.h | 2 +- src/utl/futils.h | 2 +- src/utl/log.h | 2 +- src/utl/mutex.h | 2 +- src/utl/test.h | 2 +- src/utl/thread.h | 2 +- src/utl/timer.h | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index 4045633..0789c4f 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -1,5 +1,5 @@ /** - * bitset.h + * cmc/bitset.h * * Creation Date: 30/04/2020 * diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 54d52f5..e6acdd6 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -1,5 +1,5 @@ /** - * deque.h + * cmc/deque.h * * Creation Date: 20/03/2019 * diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index 00dd671..070a6d6 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -1,5 +1,5 @@ /** - * hashbidimap.h + * cmc/hashbidimap.h * * Creation Date: 26/09/2019 * diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index ad25ae0..f981be3 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -1,5 +1,5 @@ /** - * hashmap.h + * cmc/hashmap.h * * Creation Date: 03/04/2019 * diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index 029bc8d..b7d31cd 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -1,5 +1,5 @@ /** - * hashmultimap.h + * cmc/hashmultimap.h * * Creation Date: 26/04/2019 * diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index e816b57..4b3e2a8 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -1,5 +1,5 @@ /** - * hashmultiset.h + * cmc/hashmultiset.h * * Creation Date: 10/04/2019 * diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 4b21cd9..efa0bb6 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -1,5 +1,5 @@ /** - * hashset.h + * cmc/hashset.h * * Creation Date: 01/04/2019 * diff --git a/src/cmc/heap.h b/src/cmc/heap.h index 71fbaf7..994b0b2 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -1,5 +1,5 @@ /** - * heap.h + * cmc/heap.h * * Creation Date: 25/03/2019 * diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index db61308..55dcfad 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -1,5 +1,5 @@ /** - * intervalheap.h + * cmc/intervalheap.h * * Creation Date: 06/07/2019 * diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index a5eb3a3..7d1f24f 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -1,5 +1,5 @@ /** - * linkedlist.h + * cmc/linkedlist.h * * Creation Date: 22/03/2019 * diff --git a/src/cmc/list.h b/src/cmc/list.h index a8fc1c9..5118644 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -1,5 +1,5 @@ /** - * list.h + * cmc/list.h * * Creation Date: 12/02/2019 * diff --git a/src/cmc/queue.h b/src/cmc/queue.h index 4f2148f..e2091b1 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -1,5 +1,5 @@ /** - * queue.h + * cmc/queue.h * * Creation Date: 15/02/2019 * diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h index eddf1df..ec33535 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc/sortedlist.h @@ -1,5 +1,5 @@ /** - * sortedlist.h + * cmc/sortedlist.h * * Creation Date: 17/09/2019 * diff --git a/src/cmc/stack.h b/src/cmc/stack.h index e34dc3f..f081fc9 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -1,5 +1,5 @@ /** - * stack.h + * cmc/stack.h * * Creation Date: 14/02/2019 * diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index d5c3528..72b3938 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -1,5 +1,5 @@ /** - * treemap.h + * cmc/treemap.h * * Creation Date: 28/03/2019 * diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 9d4ed3e..fa1ccfb 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -1,5 +1,5 @@ /** - * treeset.h + * cmc/treeset.h * * Creation Date: 27/03/2019 * diff --git a/src/cor/alloc.h b/src/cor/alloc.h index a8dc362..616d7d2 100644 --- a/src/cor/alloc.h +++ b/src/cor/alloc.h @@ -1,5 +1,5 @@ /** - * alloc.h + * cor/alloc.h * * Creation Date: 24/05/2020 * diff --git a/src/cor/bitset.h b/src/cor/bitset.h index cf42e57..29901a5 100644 --- a/src/cor/bitset.h +++ b/src/cor/bitset.h @@ -1,5 +1,5 @@ /** - * bitset.h + * cor/bitset.h * * Creation Date: 20/05/2020 * diff --git a/src/cor/callbacks.h b/src/cor/callbacks.h index 613eccc..5083cad 100644 --- a/src/cor/callbacks.h +++ b/src/cor/callbacks.h @@ -1,5 +1,5 @@ /** - * callbacks.h + * cor/callbacks.h * * Creation Date: 24/05/2020 * diff --git a/src/cor/core.h b/src/cor/core.h index 2a6979f..68f6832 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -1,5 +1,5 @@ /** - * core.h + * cor/core.h * * Creation Date: 17/03/2020 * diff --git a/src/cor/flags.h b/src/cor/flags.h index 3f06034..6c0827c 100644 --- a/src/cor/flags.h +++ b/src/cor/flags.h @@ -1,5 +1,5 @@ /** - * flags.h + * cor/flags.h * * Creation Date: 14/05/2020 * diff --git a/src/cor/ftable.h b/src/cor/ftable.h index 23c29a7..cdeede6 100644 --- a/src/cor/ftable.h +++ b/src/cor/ftable.h @@ -1,5 +1,5 @@ /** - * ftable.h + * cor/ftable.h * * Creation Date: 27/05/2020 * diff --git a/src/cor/hashtable.h b/src/cor/hashtable.h index d44fc51..08409db 100644 --- a/src/cor/hashtable.h +++ b/src/cor/hashtable.h @@ -1,5 +1,5 @@ /** - * hashtable.h + * cor/hashtable.h * * Creation Date: 17/03/2020 * diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 6b06766..269f20c 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -1,5 +1,5 @@ /** - * deque.h + * ext/cmc/deque.h * * Creation Date: 25/05/2020 * diff --git a/src/ext/cmc/hashbidimap.h b/src/ext/cmc/hashbidimap.h index c3cd76a..5ae56f5 100644 --- a/src/ext/cmc/hashbidimap.h +++ b/src/ext/cmc/hashbidimap.h @@ -1,5 +1,5 @@ /** - * hashbidimap.h + * ext/cmc/hashbidimap.h * * Creation Date: 26/05/2020 * diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 46f0149..d752a63 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -1,5 +1,5 @@ /** - * hashmap.h + * ext/cmc/hashmap.h * * Creation Date: 25/05/2020 * diff --git a/src/ext/cmc/hashmultimap.h b/src/ext/cmc/hashmultimap.h index fdaa9e3..1e1497a 100644 --- a/src/ext/cmc/hashmultimap.h +++ b/src/ext/cmc/hashmultimap.h @@ -1,5 +1,5 @@ /** - * hashmultimap.h + * ext/cmc/hashmultimap.h * * Creation Date: 29/05/2020 * diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h index 975b868..710dcd4 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext/cmc/hashmultiset.h @@ -1,5 +1,5 @@ /** - * hashmultiset.h + * ext/cmc/hashmultiset.h * * Creation Date: 30/05/2020 * diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h index d53d06a..a8ab725 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext/cmc/hashset.h @@ -1,5 +1,5 @@ /** - * hashset.h + * ext/cmc/hashset.h * * Creation Date: 29/05/2020 * diff --git a/src/utl/assert.h b/src/utl/assert.h index 11a8800..0d3a844 100644 --- a/src/utl/assert.h +++ b/src/utl/assert.h @@ -1,5 +1,5 @@ /** - * assert.h + * utl/assert.h * * Creation Date: 27/06/2019 * diff --git a/src/utl/foreach.h b/src/utl/foreach.h index fb6be06..f84055c 100644 --- a/src/utl/foreach.h +++ b/src/utl/foreach.h @@ -1,5 +1,5 @@ /** - * foreach.h + * utl/foreach.h * * Creation Date: 25/02/2019 * diff --git a/src/utl/futils.h b/src/utl/futils.h index 60f5f6a..28f9473 100644 --- a/src/utl/futils.h +++ b/src/utl/futils.h @@ -1,5 +1,5 @@ /** - * futils.h + * utl/futils.h * * Creation Date: 15/04/2020 * diff --git a/src/utl/log.h b/src/utl/log.h index 7566190..eada5f5 100644 --- a/src/utl/log.h +++ b/src/utl/log.h @@ -1,5 +1,5 @@ /** - * log.h + * utl/log.h * * Creation Date: 21/06/2019 * diff --git a/src/utl/mutex.h b/src/utl/mutex.h index 81f9b76..69678e6 100644 --- a/src/utl/mutex.h +++ b/src/utl/mutex.h @@ -1,5 +1,5 @@ /** - * mutex.h + * utl/mutex.h * * Creation Date: 14/05/2020 * diff --git a/src/utl/test.h b/src/utl/test.h index a127607..7111421 100644 --- a/src/utl/test.h +++ b/src/utl/test.h @@ -1,5 +1,5 @@ /** - * test.h + * utl/test.h * * Creation Date: 26/06/2019 * diff --git a/src/utl/thread.h b/src/utl/thread.h index c46950b..6848e1e 100644 --- a/src/utl/thread.h +++ b/src/utl/thread.h @@ -1,5 +1,5 @@ /** - * thread.h + * utl/thread.h * * Creation Date: 14/05/2020 * diff --git a/src/utl/timer.h b/src/utl/timer.h index cfa4357..deefdd5 100644 --- a/src/utl/timer.h +++ b/src/utl/timer.h @@ -1,5 +1,5 @@ /** - * timer.h + * utl/timer.h * * Creation Date: 12/04/2019 * From 546ac80030a9a7bfc0d18f64af04fa1f322f5ea2 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 1 Jun 2020 15:33:17 -0300 Subject: [PATCH 15/51] Adding more things to EXT and some changes to heap --- src/cmc/heap.h | 439 +++++++------------------------------ src/cor/heap.h | 31 +++ src/ext/cmc/deque.h | 25 +-- src/ext/cmc/hashmap.h | 25 +-- src/ext/cmc/hashmultimap.h | 25 +-- src/ext/cmc/hashmultiset.h | 27 ++- src/ext/cmc/hashset.h | 23 +- src/ext/cmc/heap.h | 319 +++++++++++++++++++++++++++ src/macro_collections.h | 2 + tests/main/src/heap.c | 25 +-- tests/main/unt/foreach.c | 2 +- tests/main/unt/heap.c | 54 ++--- tests/to_string.c | 7 + 13 files changed, 534 insertions(+), 470 deletions(-) create mode 100644 src/cor/heap.h create mode 100644 src/ext/cmc/heap.h diff --git a/src/cmc/heap.h b/src/cmc/heap.h index 994b0b2..b0d413f 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -38,33 +38,7 @@ /* ------------------------------------------------------------------------- * Heap Implementation * ------------------------------------------------------------------------- */ -/** - * enum cmc_heap_order - * - * Defines the two possible heaps: - * - Max Heap has the greatest element at the top - * - Min Heap has the smallest element at the top - */ -enum cmc_heap_order -{ - cmc_max_heap = 1, - cmc_min_heap = -1 -}; - -/* ------------------------------------------------------------------------- - * Heap specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "type:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p}"; +#include "../cor/heap.h" /** * Core Heap implementation @@ -84,128 +58,88 @@ static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Heap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements in the heap */ \ - size_t count; \ - \ - /* Heap order (MaxHeap or MinHeap) */ \ - enum cmc_heap_order HO; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - int (*cmp)(V, V); \ - \ - /* Copy function */ \ - V (*cpy)(V); \ - \ - /* To string function */ \ - bool (*str)(FILE *, V); \ - \ - /* Free from memory function */ \ - void (*free)(V); \ - \ - /* Hash function */ \ - size_t (*hash)(V); \ - \ - /* Priority function */ \ - int (*pri)(V, V); \ - }; \ - \ - /* Heap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target heap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, enum cmc_heap_order HO, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _heap_); \ - void CMC_(PFX, _free)(struct SNAME * _heap_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _heap_); \ - /* Element Access */ \ - V CMC_(PFX, _peek)(struct SNAME * _heap_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ - bool CMC_(PFX, _full)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ - int CMC_(PFX, _flag)(struct SNAME * _heap_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_); \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Heap Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements in the heap */ \ + size_t count; \ + \ + /* Heap order (MaxHeap or MinHeap) */ \ + enum cmc_heap_order HO; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + int (*cmp)(V, V); \ + \ + /* Copy function */ \ + V (*cpy)(V); \ + \ + /* To string function */ \ + bool (*str)(FILE *, V); \ + \ + /* Free from memory function */ \ + void (*free)(V); \ + \ + /* Hash function */ \ + size_t (*hash)(V); \ + \ + /* Priority function */ \ + int (*pri)(V, V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, enum cmc_heap_order HO, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _heap_); \ + void CMC_(PFX, _free)(struct SNAME * _heap_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _heap_); \ + /* Element Access */ \ + V CMC_(PFX, _peek)(struct SNAME * _heap_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ + bool CMC_(PFX, _full)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ + int CMC_(PFX, _flag)(struct SNAME * _heap_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); /* ------------------------------------------------------------------------- * Source @@ -226,7 +160,7 @@ static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " if (capacity < 1) \ return NULL; \ \ - if (HO != cmc_min_heap && HO != cmc_max_heap) \ + if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \ return NULL; \ \ if (!f_val) \ @@ -264,7 +198,7 @@ static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " if (capacity < 1) \ return NULL; \ \ - if (HO != cmc_min_heap && HO != cmc_max_heap) \ + if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \ return NULL; \ \ if (!f_val) \ @@ -529,209 +463,6 @@ static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " return true; \ } \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_) \ - { \ - struct cmc_string str; \ - struct SNAME *h_ = _heap_; \ - const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_heap, \ - #SNAME, #V, h_, h_->buffer, h_->capacity, h_->count, \ - t, h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - if (iter->end) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } \ - \ static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, size_t index) \ { \ /* Current index */ \ diff --git a/src/cor/heap.h b/src/cor/heap.h new file mode 100644 index 0000000..923e4e0 --- /dev/null +++ b/src/cor/heap.h @@ -0,0 +1,31 @@ +/** + * cor/heap.h + * + * Creation Date: 01/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * Things commonly used by heap collections. + */ + +#ifndef CMC_COR_HEAP_H +#define CMC_COR_HEAP_H + +/** + * enum cmc_heap_order + * + * Defines the two possible heaps: + * - Max Heap has the greatest element at the top + * - Min Heap has the smallest element at the top + */ +enum cmc_heap_order +{ + CMC_MAX_HEAP = 1, + CMC_MIN_HEAP = -1 +}; + +#endif /* CMC_COR_HEAP_H */ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 269f20c..f415475 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -18,19 +18,6 @@ */ #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 * @@ -374,6 +361,18 @@ static const char *cmc_cmc_string_fmt_deque = "struct %s<%s> " /** * 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 }"; + #define CMC_EXT_CMC_DEQUE_STR(BODY) \ CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \ CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY) diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index d752a63..b490457 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -18,19 +18,6 @@ */ #define CMC_EXT_CMC_HASHMAP_PARTS INIT, ITER, 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 * @@ -450,6 +437,18 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " /** * 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 }"; + #define CMC_EXT_CMC_HASHMAP_STR(BODY) \ CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \ CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY) diff --git a/src/ext/cmc/hashmultimap.h b/src/ext/cmc/hashmultimap.h index 1e1497a..c21320e 100644 --- a/src/ext/cmc/hashmultimap.h +++ b/src/ext/cmc/hashmultimap.h @@ -18,19 +18,6 @@ */ #define CMC_EXT_CMC_HASHMULTIMAP_PARTS ITER, STR -/* Used by STR */ -static const char *cmc_cmc_string_fmt_hashmultimap = "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 }"; - /** * ITER */ @@ -392,6 +379,18 @@ static const char *cmc_cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " /** * STR */ +static const char *cmc_cmc_string_fmt_hashmultimap = "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 }"; + #define CMC_EXT_CMC_HASHMULTIMAP_STR(BODY) \ CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(BODY) \ CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(BODY) diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h index 710dcd4..eba045a 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext/cmc/hashmultiset.h @@ -18,20 +18,6 @@ */ #define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, STR -/* Used by STR */ -static const char *cmc_cmc_string_fmt_hashmultiset = - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "cardinality:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * ITER */ @@ -359,6 +345,19 @@ static const char *cmc_cmc_string_fmt_hashmultiset = /** * STR */ +static const char *cmc_cmc_string_fmt_hashmultiset = + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "cardinality:%" PRIuMAX ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }"; + #define CMC_EXT_CMC_HASHMULTISET_STR(BODY) \ CMC_EXT_CMC_HASHMULTISET_STR_HEADER(BODY) \ CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(BODY) diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h index a8ab725..5149f28 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext/cmc/hashset.h @@ -18,18 +18,6 @@ */ #define CMC_EXT_CMC_HASHSET_PARTS ITER, STR -/* Used by STR */ -static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p }"; - /** * ITER */ @@ -348,6 +336,17 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " /** * STR */ +static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p }"; + #define CMC_EXT_CMC_HASHSET_STR(BODY) \ CMC_EXT_CMC_HASHSET_STR_HEADER(BODY) \ CMC_EXT_CMC_HASHSET_STR_SOURCE(BODY) diff --git a/src/ext/cmc/heap.h b/src/ext/cmc/heap.h new file mode 100644 index 0000000..b999b12 --- /dev/null +++ b/src/ext/cmc/heap.h @@ -0,0 +1,319 @@ +/** + * ext/cmc/heap.h + * + * Creation Date: 01/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_HEAP_H +#define CMC_EXT_CMC_HEAP_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC Heap. + */ +#define CMC_EXT_CMC_HEAP_PARTS ITER, STR + +#define CMC_EXT_CMC_HEAP_ITER(BODY) \ + CMC_EXT_CMC_HEAP_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HEAP_ITER_SOURCE(BODY) + +#define CMC_EXT_CMC_HEAP_ITER_HEADER(BODY) \ + CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HEAP_ITER_SOURCE(BODY) \ + CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* Heap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target heap */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_HEAP_ITER_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor++; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor--; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ + \ + if (iter->end) \ + return false; \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor += steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor < steps) \ + return false; \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor -= steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor]; \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ + } + +/** + * STR + */ +static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "type:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p}"; + +#define CMC_EXT_CMC_HEAP_STR(BODY) \ + CMC_EXT_CMC_HEAP_STR_HEADER(BODY) \ + CMC_EXT_CMC_HEAP_STR_SOURCE(BODY) + +#define CMC_EXT_CMC_HEAP_STR_HEADER(BODY) \ + CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HEAP_STR_SOURCE(BODY) \ + CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ + CMC_PARAM_V(BODY)) + +#define CMC_EXT_CMC_HEAP_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_HEAP_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ + { \ + struct SNAME *h_ = _heap_; \ + const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \ + \ + return 0 <= fprintf(fptr, cmc_cmc_string_fmt_heap, \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, \ + h_->buffer, h_->capacity, h_->count, t, h_->flag, \ + h_->f_val, h_->alloc, h_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \ + return false; \ + \ + if (i + 1 < _heap_->count) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_HEAP_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 237b580..a49ba68 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -51,12 +51,14 @@ #include "cor/flags.h" /* Added in 14/05/2020 */ #include "cor/ftable.h" /* Added in 27/05/2020 */ #include "cor/hashtable.h" /* Added in 17/03/2020 */ +#include "cor/heap.h" /* Added in 01/06/2020 */ #include "ext/cmc/deque.h" /* Added in 25/05/2020 */ #include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ #include "ext/cmc/hashmultimap.h" /* Added in 29/05/2020 */ #include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */ #include "ext/cmc/hashset.h" /* Added in 31/05/2020 */ +#include "ext/cmc/heap.h" /* Added in 01/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/main/src/heap.c b/tests/main/src/heap.c index fefc99f..4c04496 100644 --- a/tests/main/src/heap.c +++ b/tests/main/src/heap.c @@ -74,7 +74,7 @@ struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity < 1) return ((void *)0); - if (HO != cmc_min_heap && HO != cmc_max_heap) + if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) return ((void *)0); if (!f_val) return ((void *)0); @@ -102,7 +102,7 @@ struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, { if (capacity < 1) return ((void *)0); - if (HO != cmc_min_heap && HO != cmc_max_heap) + if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) return ((void *)0); if (!f_val) return ((void *)0); @@ -300,27 +300,6 @@ _Bool h_equals(struct heap *_heap1_, struct heap *_heap2_) } return 1; } -struct cmc_string h_to_string(struct heap *_heap_) -{ - struct cmc_string str; - struct heap *h_ = _heap_; - const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_heap, - "CMC_PARAM_SNAME((h, heap, , , size_t))", - "CMC_PARAM_V((h, heap, , , size_t))", h_, h_->buffer, - h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, - h_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool h_print(struct heap *_heap_, FILE *fptr) -{ - for (size_t i = 0; i < _heap_->count; i++) - { - if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) - return 0; - } - return 1; -} struct heap_iter h_iter_start(struct heap *target) { struct heap_iter iter; diff --git a/tests/main/unt/foreach.c b/tests/main/unt/foreach.c index de2d7f7..ef93289 100644 --- a/tests/main/unt/foreach.c +++ b/tests/main/unt/foreach.c @@ -231,7 +231,7 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct heap *h = h_new(10000, cmc_max_heap, + struct heap *h = h_new(10000, CMC_MAX_HEAP, &(struct heap_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, diff --git a/tests/main/unt/heap.c b/tests/main/unt/heap.c index 5dbaaa7..0bd09ff 100644 --- a/tests/main/unt/heap.c +++ b/tests/main/unt/heap.c @@ -13,7 +13,7 @@ struct heap_fval *h_fval = &(struct heap_fval){ .cmp = cmc_size_cmp, CMC_CREATE_UNIT(Heap, true, { CMC_CREATE_TEST(new, { - struct heap *h = h_new(1000000, cmc_max_heap, h_fval); + struct heap *h = h_new(1000000, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); cmc_assert_not_equals(ptr, NULL, h->buffer); @@ -24,19 +24,19 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(new[edge_case capacity = 0], { - struct heap *h = h_new(0, cmc_max_heap, h_fval); + struct heap *h = h_new(0, CMC_MAX_HEAP, h_fval); cmc_assert_equals(ptr, NULL, h); }); CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { - struct heap *h = h_new(UINT64_MAX, cmc_max_heap, h_fval); + struct heap *h = h_new(UINT64_MAX, CMC_MAX_HEAP, h_fval); cmc_assert_equals(ptr, NULL, h); }); CMC_CREATE_TEST(clear[count capacity], { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -54,7 +54,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], { - struct heap *h = h_new(1, cmc_max_heap, h_fval); + struct heap *h = h_new(1, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -67,7 +67,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(insert, { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -77,7 +77,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(insert[item preservation], { - struct heap *h = h_new(50, cmc_max_heap, h_fval); + struct heap *h = h_new(50, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -94,7 +94,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(remove, { - struct heap *h = h_new(50, cmc_max_heap, h_fval); + struct heap *h = h_new(50, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -109,7 +109,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(remove[count = 0], { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -119,7 +119,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(remove[sorted], { - struct heap *h = h_new(100, cmc_min_heap, h_fval); + struct heap *h = h_new(100, CMC_MIN_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -141,7 +141,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(peek, { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -154,7 +154,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(peek[count = 0], { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -164,7 +164,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(flags, { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); @@ -223,7 +223,7 @@ CMC_CREATE_UNIT(Heap, true, { CMC_CREATE_TEST(callbacks, { struct heap *h = - h_new_custom(100, cmc_max_heap, h_fval, NULL, callbacks); + h_new_custom(100, CMC_MAX_HEAP, h_fval, NULL, callbacks); cmc_assert_not_equals(ptr, NULL, h); @@ -293,7 +293,7 @@ CMC_CREATE_UNIT(Heap, true, { CMC_CREATE_UNIT(HeapIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -319,7 +319,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_end(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -346,7 +346,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -368,7 +368,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -390,7 +390,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -422,7 +422,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -450,7 +450,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_next(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -488,7 +488,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_prev(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -526,7 +526,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_advance(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -577,7 +577,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -628,7 +628,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -669,7 +669,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_value(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); @@ -689,7 +689,7 @@ CMC_CREATE_UNIT(HeapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_index(), { - struct heap *h = h_new(100, cmc_max_heap, h_fval); + struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); cmc_assert_not_equals(ptr, NULL, h); diff --git a/tests/to_string.c b/tests/to_string.c index 531bfb6..3c0365c 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -8,6 +8,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h, heap, , , int)) struct { @@ -31,6 +32,7 @@ int main(void) (struct hashmultiset_fval *)&int_ftab); struct hashset *hs = hs_new(100, 0.6, (struct hashset_fval *)&int_ftab); + struct heap *h = h_new(100, CMC_MAX_HEAP, (struct heap_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -42,6 +44,8 @@ int main(void) hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); hs_to_string(hs, stdout); hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); + h_to_string(h, stdout); + h_print(h, stdout, "\n[ ", ", ", " ]\n"); for (int i = 0; i < 20; i++) { @@ -50,6 +54,7 @@ int main(void) hmm_insert(hmm, i, i); hms_insert(hms, i); hs_insert(hs, i); + h_insert(h, i); } fprintf(stdout, "\n"); @@ -64,6 +69,8 @@ int main(void) hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); hs_to_string(hs, stdout); hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); + h_to_string(h, stdout); + h_print(h, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm); From 9209e0d5ec2a6b505c70f7a6709599dc7364e1b6 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 1 Jun 2020 20:01:54 -0300 Subject: [PATCH 16/51] Refactoring Now using CMC_DEF_FTAB macros Renamed BODY to PARAMS --- src/cmc/bitset.h | 14 ++++---- src/cmc/deque.h | 18 +++++------ src/cmc/hashbidimap.h | 46 +++++++++++++------------- src/cmc/hashmap.h | 44 +++++++++++++------------ src/cmc/hashmultimap.h | 46 +++++++++++++------------- src/cmc/hashmultiset.h | 30 ++++++++--------- src/cmc/hashset.h | 30 ++++++++--------- src/cmc/heap.h | 30 ++++++++--------- src/cmc/intervalheap.h | 30 ++++++++--------- src/cmc/linkedlist.h | 30 ++++++++--------- src/cmc/list.h | 30 ++++++++--------- src/cmc/queue.h | 30 ++++++++--------- src/cmc/sortedlist.h | 30 ++++++++--------- src/cmc/stack.h | 30 ++++++++--------- src/cmc/treemap.h | 44 +++++++++++++------------ src/cmc/treeset.h | 30 ++++++++--------- src/ext/cmc/deque.h | 54 +++++++++++++++---------------- src/ext/cmc/hashmap.h | 66 +++++++++++++++++++------------------- src/ext/cmc/hashmultimap.h | 44 ++++++++++++------------- src/ext/cmc/hashmultiset.h | 36 ++++++++++----------- src/ext/cmc/hashset.h | 36 ++++++++++----------- src/ext/cmc/heap.h | 36 ++++++++++----------- 22 files changed, 394 insertions(+), 390 deletions(-) diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index 0789c4f..f55bf96 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -56,15 +56,15 @@ static const char *cmc_cmc_string_fmt_bitset = "struct %s " /** * Core BitSet implementation */ -#define CMC_CMC_BITSET_CORE(BODY) \ - CMC_CMC_BITSET_CORE_HEADER(BODY) \ - CMC_CMC_BITSET_CORE_SOURCE(BODY) +#define CMC_CMC_BITSET_CORE(PARAMS) \ + CMC_CMC_BITSET_CORE_HEADER(PARAMS) \ + CMC_CMC_BITSET_CORE_SOURCE(PARAMS) -#define CMC_CMC_BITSET_CORE_HEADER(BODY) \ - CMC_CMC_BITSET_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY)) +#define CMC_CMC_BITSET_CORE_HEADER(PARAMS) \ + CMC_CMC_BITSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) -#define CMC_CMC_BITSET_CORE_SOURCE(BODY) \ - CMC_CMC_BITSET_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY)) +#define CMC_CMC_BITSET_CORE_SOURCE(PARAMS) \ + CMC_CMC_BITSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) /* ------------------------------------------------------------------------- * Header diff --git a/src/cmc/deque.h b/src/cmc/deque.h index e6acdd6..4ade839 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -43,17 +43,17 @@ /** * Core Deque implementation */ -#define CMC_CMC_DEQUE_CORE(BODY) \ - CMC_CMC_DEQUE_CORE_HEADER(BODY) \ - CMC_CMC_DEQUE_CORE_SOURCE(BODY) +#define CMC_CMC_DEQUE_CORE(PARAMS) \ + CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \ + CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) -#define CMC_CMC_DEQUE_CORE_HEADER(BODY) \ - CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \ + CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_DEQUE_CORE_SOURCE(BODY) \ - CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) \ + CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index 070a6d6..cbafa1f 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -55,19 +55,19 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " /** * Core HashBidiMap implementation */ -#define CMC_CMC_HASHBIDIMAP_CORE(BODY) \ - CMC_CMC_HASHBIDIMAP_CORE_HEADER(BODY) \ - CMC_CMC_HASHBIDIMAP_CORE_SOURCE(BODY) +#define CMC_CMC_HASHBIDIMAP_CORE(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHBIDIMAP_CORE_HEADER(BODY) \ - CMC_CMC_HASHBIDIMAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE(BODY) \ - CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -138,44 +138,44 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " struct CMC_DEF_FKEY(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(K, K); \ + CMC_DEF_FTAB_CMP(K); \ \ /* Copy function */ \ - K (*cpy)(K); \ + CMC_DEF_FTAB_CPY(K); \ \ /* To string function */ \ - bool (*str)(FILE *, K); \ + CMC_DEF_FTAB_STR(K); \ \ /* Free from memory function */ \ - void (*free)(K); \ + CMC_DEF_FTAB_FREE(K); \ \ /* Hash function */ \ - size_t (*hash)(K); \ + CMC_DEF_FTAB_HASH(K); \ \ /* Priority function */ \ - int (*pri)(K, K); \ + CMC_DEF_FTAB_PRI(K); \ }; \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* HashBidiMap Iterator */ \ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index f981be3..e768b2c 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -32,17 +32,19 @@ /** * Core HashMap implementation */ -#define CMC_CMC_HASHMAP_CORE(BODY) \ - CMC_CMC_HASHMAP_CORE_HEADER(BODY) \ - CMC_CMC_HASHMAP_CORE_SOURCE(BODY) +#define CMC_CMC_HASHMAP_CORE(PARAMS) \ + CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHMAP_CORE_HEADER(BODY) \ - CMC_CMC_HASHMAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHMAP_CORE_SOURCE(BODY) \ - CMC_CMC_HASHMAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -101,44 +103,44 @@ struct CMC_DEF_FKEY(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(K, K); \ + CMC_DEF_FTAB_CMP(K); \ \ /* Copy function */ \ - K (*cpy)(K); \ + CMC_DEF_FTAB_CPY(K); \ \ /* To string function */ \ - bool (*str)(FILE *, K); \ + CMC_DEF_FTAB_STR(K); \ \ /* Free from memory function */ \ - void (*free)(K); \ + CMC_DEF_FTAB_FREE(K); \ \ /* Hash function */ \ - size_t (*hash)(K); \ + CMC_DEF_FTAB_HASH(K); \ \ /* Priority function */ \ - int (*pri)(K, K); \ + CMC_DEF_FTAB_PRI(K); \ }; \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Collection Functions */ \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index b7d31cd..f46d1a5 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -57,19 +57,19 @@ /** * Core HashMultiMap implementation */ -#define CMC_CMC_HASHMULTIMAP_CORE(BODY) \ - CMC_CMC_HASHMULTIMAP_CORE_HEADER(BODY) \ - CMC_CMC_HASHMULTIMAP_CORE_SOURCE(BODY) +#define CMC_CMC_HASHMULTIMAP_CORE(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHMULTIMAP_CORE_HEADER(BODY) \ - CMC_CMC_HASHMULTIMAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE(BODY) \ - CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -127,44 +127,44 @@ struct CMC_DEF_FKEY(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(K, K); \ + CMC_DEF_FTAB_CMP(K); \ \ /* Copy function */ \ - K (*cpy)(K); \ + CMC_DEF_FTAB_CPY(K); \ \ /* To string function */ \ - bool (*str)(FILE *, K); \ + CMC_DEF_FTAB_STR(K); \ \ /* Free from memory function */ \ - void (*free)(K); \ + CMC_DEF_FTAB_FREE(K); \ \ /* Hash function */ \ - size_t (*hash)(K); \ + CMC_DEF_FTAB_HASH(K); \ \ /* Priority function */ \ - int (*pri)(K, K); \ + CMC_DEF_FTAB_PRI(K); \ }; \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Collection Functions */ \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index 4b3e2a8..daaa563 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -39,17 +39,17 @@ /** * Core HashMultiSet implementation */ -#define CMC_CMC_HASHMULTISET_CORE(BODY) \ - CMC_CMC_HASHMULTISET_CORE_HEADER(BODY) \ - CMC_CMC_HASHMULTISET_CORE_SOURCE(BODY) +#define CMC_CMC_HASHMULTISET_CORE(PARAMS) \ + CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHMULTISET_CORE_HEADER(BODY) \ - CMC_CMC_HASHMULTISET_CORE_HEADER_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHMULTISET_CORE_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHMULTISET_CORE_SOURCE(BODY) \ - CMC_CMC_HASHMULTISET_CORE_SOURCE_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHMULTISET_CORE_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -107,22 +107,22 @@ struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Collection Functions */ \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index efa0bb6..8af3ec2 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -32,17 +32,17 @@ /** * Core HashSet implementation */ -#define CMC_CMC_HASHSET_CORE(BODY) \ - CMC_CMC_HASHSET_CORE_HEADER(BODY) \ - CMC_CMC_HASHSET_CORE_SOURCE(BODY) +#define CMC_CMC_HASHSET_CORE(PARAMS) \ + CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHSET_CORE_HEADER(BODY) \ - CMC_CMC_HASHSET_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHSET_CORE_SOURCE(BODY) \ - CMC_CMC_HASHSET_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -94,22 +94,22 @@ struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Collection Functions */ \ diff --git a/src/cmc/heap.h b/src/cmc/heap.h index b0d413f..e30cba8 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -43,17 +43,17 @@ /** * Core Heap implementation */ -#define CMC_CMC_HEAP_CORE(BODY) \ - CMC_CMC_HEAP_CORE_HEADER(BODY) \ - CMC_CMC_HEAP_CORE_SOURCE(BODY) +#define CMC_CMC_HEAP_CORE(PARAMS) \ + CMC_CMC_HEAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HEAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_HEAP_CORE_HEADER(BODY) \ - CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_HEAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HEAP_CORE_SOURCE(BODY) \ - CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_HEAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -92,22 +92,22 @@ struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Collection Functions */ \ diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index 55dcfad..a1e23ea 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -44,17 +44,17 @@ static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " /** * Core IntervalHeap implementation */ -#define CMC_CMC_INTERVALHEAP_CORE(BODY) \ - CMC_CMC_INTERVALHEAP_CORE_HEADER(BODY) \ - CMC_CMC_INTERVALHEAP_CORE_SOURCE(BODY) +#define CMC_CMC_INTERVALHEAP_CORE(PARAMS) \ + CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) \ + CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_INTERVALHEAP_CORE_HEADER(BODY) \ - CMC_CMC_INTERVALHEAP_CORE_HEADER_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) \ + CMC_CMC_INTERVALHEAP_CORE_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_INTERVALHEAP_CORE_SOURCE(BODY) \ - CMC_CMC_INTERVALHEAP_CORE_SOURCE_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_INTERVALHEAP_CORE_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -94,22 +94,22 @@ static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Heap Iterator */ \ diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index 7d1f24f..7d76647 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -50,17 +50,17 @@ static const char *cmc_cmc_string_fmt_linkedlist = "struct %s<%s> " /** * Core LinkedList implementation */ -#define CMC_CMC_LINKEDLIST_CORE(BODY) \ - CMC_CMC_LINKEDLIST_CORE_HEADER(BODY) \ - CMC_CMC_LINKEDLIST_CORE_SOURCE(BODY) +#define CMC_CMC_LINKEDLIST_CORE(PARAMS) \ + CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) \ + CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) -#define CMC_CMC_LINKEDLIST_CORE_HEADER(BODY) \ - CMC_CMC_LINKEDLIST_CORE_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) \ + CMC_CMC_LINKEDLIST_CORE_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_LINKEDLIST_CORE_SOURCE(BODY) \ - CMC_CMC_LINKEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) \ + CMC_CMC_LINKEDLIST_CORE_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -109,22 +109,22 @@ static const char *cmc_cmc_string_fmt_linkedlist = "struct %s<%s> " struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Linked List Iterator */ \ diff --git a/src/cmc/list.h b/src/cmc/list.h index 5118644..d0254cd 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -65,17 +65,17 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " /** * Core List implementation */ -#define CMC_CMC_LIST_CORE(BODY) \ - CMC_CMC_LIST_CORE_HEADER(BODY) \ - CMC_CMC_LIST_CORE_SOURCE(BODY) +#define CMC_CMC_LIST_CORE(PARAMS) \ + CMC_CMC_LIST_CORE_HEADER(PARAMS) \ + CMC_CMC_LIST_CORE_SOURCE(PARAMS) -#define CMC_CMC_LIST_CORE_HEADER(BODY) \ - CMC_CMC_LIST_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_LIST_CORE_HEADER(PARAMS) \ + CMC_CMC_LIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_LIST_CORE_SOURCE(BODY) \ - CMC_CMC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_LIST_CORE_SOURCE(PARAMS) \ + CMC_CMC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -111,22 +111,22 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* List Iterator */ \ diff --git a/src/cmc/queue.h b/src/cmc/queue.h index e2091b1..43a897a 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -67,17 +67,17 @@ static const char *cmc_cmc_string_fmt_queue = "struct %s<%s> " /** * Core Queue implementation */ -#define CMC_CMC_QUEUE_CORE(BODY) \ - CMC_CMC_QUEUE_CORE_HEADER(BODY) \ - CMC_CMC_QUEUE_CORE_SOURCE(BODY) +#define CMC_CMC_QUEUE_CORE(PARAMS) \ + CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \ + CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) -#define CMC_CMC_QUEUE_CORE_HEADER(BODY) \ - CMC_CMC_QUEUE_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \ + CMC_CMC_QUEUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_QUEUE_CORE_SOURCE(BODY) \ - CMC_CMC_QUEUE_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) \ + CMC_CMC_QUEUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -119,22 +119,22 @@ static const char *cmc_cmc_string_fmt_queue = "struct %s<%s> " struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Queue Iterator */ \ diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h index ec33535..ac0be3f 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc/sortedlist.h @@ -45,17 +45,17 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " /** * Core SortedList implementation */ -#define CMC_CMC_SORTEDLIST_CORE(BODY) \ - CMC_CMC_SORTEDLIST_CORE_HEADER(BODY) \ - CMC_CMC_SORTEDLIST_CORE_SOURCE(BODY) +#define CMC_CMC_SORTEDLIST_CORE(PARAMS) \ + CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) \ + CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) -#define CMC_CMC_SORTEDLIST_CORE_HEADER(BODY) \ - CMC_CMC_SORTEDLIST_CORE_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) \ + CMC_CMC_SORTEDLIST_CORE_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_SORTEDLIST_CORE_SOURCE(BODY) \ - CMC_CMC_SORTEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) \ + CMC_CMC_SORTEDLIST_CORE_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -94,22 +94,22 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* List Iterator */ \ diff --git a/src/cmc/stack.h b/src/cmc/stack.h index f081fc9..defd64a 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -50,17 +50,17 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " /** * Core Stack implementation */ -#define CMC_CMC_STACK_CORE(BODY) \ - CMC_CMC_STACK_CORE_HEADER(BODY) \ - CMC_CMC_STACK_CORE_SOURCE(BODY) +#define CMC_CMC_STACK_CORE(PARAMS) \ + CMC_CMC_STACK_CORE_HEADER(PARAMS) \ + CMC_CMC_STACK_CORE_SOURCE(PARAMS) -#define CMC_CMC_STACK_CORE_HEADER(BODY) \ - CMC_CMC_STACK_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_STACK_CORE_HEADER(PARAMS) \ + CMC_CMC_STACK_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_STACK_CORE_SOURCE(BODY) \ - CMC_CMC_STACK_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_STACK_CORE_SOURCE(PARAMS) \ + CMC_CMC_STACK_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -96,22 +96,22 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Stack Iterator */ \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index 72b3938..c064d31 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -41,17 +41,19 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " /** * Core TreeMap implementation */ -#define CMC_CMC_TREEMAP_CORE(BODY) \ - CMC_CMC_TREEMAP_CORE_HEADER(BODY) \ - CMC_CMC_TREEMAP_CORE_SOURCE(BODY) +#define CMC_CMC_TREEMAP_CORE(PARAMS) \ + CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_TREEMAP_CORE_HEADER(BODY) \ - CMC_CMC_TREEMAP_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_TREEMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_TREEMAP_CORE_SOURCE(BODY) \ - CMC_CMC_TREEMAP_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) +#define CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_TREEMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -109,44 +111,44 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " struct CMC_DEF_FKEY(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(K, K); \ + CMC_DEF_FTAB_CMP(K); \ \ /* Copy function */ \ - K (*cpy)(K); \ + CMC_DEF_FTAB_CPY(K); \ \ /* To string function */ \ - bool (*str)(FILE *, K); \ + CMC_DEF_FTAB_STR(K); \ \ /* Free from memory function */ \ - void (*free)(K); \ + CMC_DEF_FTAB_FREE(K); \ \ /* Hash function */ \ - size_t (*hash)(K); \ + CMC_DEF_FTAB_HASH(K); \ \ /* Priority function */ \ - int (*pri)(K, K); \ + CMC_DEF_FTAB_PRI(K); \ }; \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Treemap Iterator */ \ diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index fa1ccfb..589e07c 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -40,17 +40,17 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " /** * Core TreeSet implementation */ -#define CMC_CMC_TREESET_CORE(BODY) \ - CMC_CMC_TREESET_CORE_HEADER(BODY) \ - CMC_CMC_TREESET_CORE_SOURCE(BODY) +#define CMC_CMC_TREESET_CORE(PARAMS) \ + CMC_CMC_TREESET_CORE_HEADER(PARAMS) \ + CMC_CMC_TREESET_CORE_SOURCE(PARAMS) -#define CMC_CMC_TREESET_CORE_HEADER(BODY) \ - CMC_CMC_TREESET_CORE_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_TREESET_CORE_HEADER(PARAMS) \ + CMC_CMC_TREESET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_TREESET_CORE_SOURCE(BODY) \ - CMC_CMC_TREESET_CORE_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_CMC_TREESET_CORE_SOURCE(PARAMS) \ + CMC_CMC_TREESET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header @@ -102,22 +102,22 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " struct CMC_DEF_FVAL(SNAME) \ { \ /* Comparator function */ \ - int (*cmp)(V, V); \ + CMC_DEF_FTAB_CMP(V); \ \ /* Copy function */ \ - V (*cpy)(V); \ + CMC_DEF_FTAB_CPY(V); \ \ /* To string function */ \ - bool (*str)(FILE *, V); \ + CMC_DEF_FTAB_STR(V); \ \ /* Free from memory function */ \ - void (*free)(V); \ + CMC_DEF_FTAB_FREE(V); \ \ /* Hash function */ \ - size_t (*hash)(V); \ + CMC_DEF_FTAB_HASH(V); \ \ /* Priority function */ \ - int (*pri)(V, V); \ + CMC_DEF_FTAB_PRI(V); \ }; \ \ /* Treeset Iterator */ \ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index f415475..9106969 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -24,17 +24,17 @@ * The part 'INIT' gives a new way of initializing a collection. The collection * struct is not heap allocated, only its internal structure (nodes, buffers). */ -#define CMC_EXT_CMC_DEQUE_INIT(BODY) \ - CMC_EXT_CMC_DEQUE_INIT_HEADER(BODY) \ - CMC_EXT_CMC_DEQUE_INIT_SOURCE(BODY) +#define CMC_EXT_CMC_DEQUE_INIT(PARAMS) \ + CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \ + CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS) -#define CMC_EXT_CMC_DEQUE_INIT_HEADER(BODY) \ - CMC_EXT_CMC_DEQUE_INIT_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \ + CMC_EXT_CMC_DEQUE_INIT_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_INIT_SOURCE(BODY) \ - CMC_EXT_CMC_DEQUE_INIT_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS) \ + CMC_EXT_CMC_DEQUE_INIT_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ \ @@ -87,17 +87,17 @@ /** * ITER */ -#define CMC_EXT_CMC_DEQUE_ITER(BODY) \ - CMC_EXT_CMC_DEQUE_ITER_HEADER(BODY) \ - CMC_EXT_CMC_DEQUE_ITER_SOURCE(BODY) +#define CMC_EXT_CMC_DEQUE_ITER(PARAMS) \ + CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS) -#define CMC_EXT_CMC_DEQUE_ITER_HEADER(BODY) \ - CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_DEQUE_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_ITER_SOURCE(BODY) \ - CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_DEQUE_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \ \ @@ -373,17 +373,17 @@ static const char *cmc_cmc_string_fmt_deque = "struct %s<%s> " "alloc:%p, " "callbacks:%p }"; -#define CMC_EXT_CMC_DEQUE_STR(BODY) \ - CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \ - CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY) +#define CMC_EXT_CMC_DEQUE_STR(PARAMS) \ + CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_DEQUE_STR_HEADER(BODY) \ - CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_DEQUE_STR_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_STR_SOURCE(BODY) \ - CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_DEQUE_STR_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \ \ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index b490457..3354a21 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -24,19 +24,19 @@ * The part 'INIT' gives a new way of initializing a collection. The collection * struct is not heap allocated, only its internal structure (nodes, buffers). */ -#define CMC_EXT_CMC_HASHMAP_INIT(BODY) \ - CMC_EXT_CMC_HASHMAP_INIT_HEADER(BODY) \ - CMC_EXT_CMC_HASHMAP_INIT_SOURCE(BODY) +#define CMC_EXT_CMC_HASHMAP_INIT(PARAMS) \ + CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS) -#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_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) -#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_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(PFX, SNAME, K, V) \ \ @@ -102,19 +102,19 @@ /** * ITER */ -#define CMC_EXT_CMC_HASHMAP_ITER(BODY) \ - CMC_EXT_CMC_HASHMAP_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HASHMAP_ITER_SOURCE(BODY) +#define CMC_EXT_CMC_HASHMAP_ITER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE(BODY) \ - CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \ \ @@ -449,19 +449,19 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " "alloc:%p, " "callbacks:%p }"; -#define CMC_EXT_CMC_HASHMAP_STR(BODY) \ - CMC_EXT_CMC_HASHMAP_STR_HEADER(BODY) \ - CMC_EXT_CMC_HASHMAP_STR_SOURCE(BODY) +#define CMC_EXT_CMC_HASHMAP_STR(PARAMS) \ + CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS) -#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_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) -#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_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), \ + CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, K, V) \ \ diff --git a/src/ext/cmc/hashmultimap.h b/src/ext/cmc/hashmultimap.h index c21320e..51c8436 100644 --- a/src/ext/cmc/hashmultimap.h +++ b/src/ext/cmc/hashmultimap.h @@ -21,19 +21,19 @@ /** * ITER */ -#define CMC_EXT_CMC_HASHMULTIMAP_ITER(BODY) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(BODY) +#define CMC_EXT_CMC_HASHMULTIMAP_ITER(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(BODY) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_K(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \ \ @@ -391,19 +391,19 @@ static const char *cmc_cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " "alloc:%p, " "callbacks:%p }"; -#define CMC_EXT_CMC_HASHMULTIMAP_STR(BODY) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(BODY) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(BODY) +#define CMC_EXT_CMC_HASHMULTIMAP_STR(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(BODY) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(BODY) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_K(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(PFX, SNAME, K, V) \ \ diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h index eba045a..c2d10c5 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext/cmc/hashmultiset.h @@ -21,17 +21,17 @@ /** * ITER */ -#define CMC_EXT_CMC_HASHMULTISET_ITER(BODY) \ - CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(BODY) +#define CMC_EXT_CMC_HASHMULTISET_ITER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(BODY) \ - CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(PFX, SNAME, V) \ \ @@ -358,17 +358,17 @@ static const char *cmc_cmc_string_fmt_hashmultiset = "alloc:%p, " "callbacks:%p }"; -#define CMC_EXT_CMC_HASHMULTISET_STR(BODY) \ - CMC_EXT_CMC_HASHMULTISET_STR_HEADER(BODY) \ - CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(BODY) +#define CMC_EXT_CMC_HASHMULTISET_STR(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER(BODY) \ - CMC_EXT_CMC_HASHMULTISET_STR_HEADER_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_STR_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(BODY) \ - CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_( \ - CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(PFX, SNAME, V) \ \ diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h index 5149f28..344738c 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext/cmc/hashset.h @@ -21,17 +21,17 @@ /** * ITER */ -#define CMC_EXT_CMC_HASHSET_ITER(BODY) \ - CMC_EXT_CMC_HASHSET_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HASHSET_ITER_SOURCE(BODY) +#define CMC_EXT_CMC_HASHSET_ITER(PARAMS) \ + CMC_EXT_CMC_HASHSET_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_ITER_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHSET_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHSET_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHSET_ITER_SOURCE(BODY) \ - CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHSET_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHSET_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHSET_ITER_HEADER_(PFX, SNAME, V) \ \ @@ -347,17 +347,17 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " "alloc:%p, " "callbacks: %p }"; -#define CMC_EXT_CMC_HASHSET_STR(BODY) \ - CMC_EXT_CMC_HASHSET_STR_HEADER(BODY) \ - CMC_EXT_CMC_HASHSET_STR_SOURCE(BODY) +#define CMC_EXT_CMC_HASHSET_STR(PARAMS) \ + CMC_EXT_CMC_HASHSET_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHSET_STR_HEADER(BODY) \ - CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHSET_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_STR_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHSET_STR_SOURCE(BODY) \ - CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(BODY), \ - CMC_PARAM_SNAME(BODY), CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HASHSET_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHSET_STR_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHSET_STR_HEADER_(PFX, SNAME, V) \ \ diff --git a/src/ext/cmc/heap.h b/src/ext/cmc/heap.h index b999b12..bc98c8d 100644 --- a/src/ext/cmc/heap.h +++ b/src/ext/cmc/heap.h @@ -18,17 +18,17 @@ */ #define CMC_EXT_CMC_HEAP_PARTS ITER, STR -#define CMC_EXT_CMC_HEAP_ITER(BODY) \ - CMC_EXT_CMC_HEAP_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HEAP_ITER_SOURCE(BODY) +#define CMC_EXT_CMC_HEAP_ITER(PARAMS) \ + CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS) -#define CMC_EXT_CMC_HEAP_ITER_HEADER(BODY) \ - CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HEAP_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HEAP_ITER_SOURCE(BODY) \ - CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_HEAP_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \ \ @@ -264,17 +264,17 @@ static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " "alloc:%p, " "callbacks: %p}"; -#define CMC_EXT_CMC_HEAP_STR(BODY) \ - CMC_EXT_CMC_HEAP_STR_HEADER(BODY) \ - CMC_EXT_CMC_HEAP_STR_SOURCE(BODY) +#define CMC_EXT_CMC_HEAP_STR(PARAMS) \ + CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_HEAP_STR_HEADER(BODY) \ - CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HEAP_STR_SOURCE(BODY) \ - CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(BODY), CMC_PARAM_SNAME(BODY), \ - CMC_PARAM_V(BODY)) +#define CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HEAP_STR_HEADER_(PFX, SNAME, V) \ \ From 424ba074ffc39c066035ecaa675ddfe8b386108a Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 2 Jun 2020 11:14:34 -0300 Subject: [PATCH 17/51] Inlining string_fmt and fixing some unused warnings with __attribute__ --- src/cmc/hashset.h | 4 ---- src/cor/core.h | 6 ++++++ src/dev/deque.h | 0 src/ext/cmc/deque.h | 25 ++++++++++++------------- src/ext/cmc/hashmap.h | 25 ++++++++++++------------- src/ext/cmc/hashmultimap.h | 25 ++++++++++++------------- src/ext/cmc/hashmultiset.h | 26 ++++++++++++-------------- src/ext/cmc/hashset.h | 23 +++++++++++------------ src/ext/cmc/heap.h | 23 +++++++++++------------ src/utl/assert.h | 8 +++++--- src/utl/log.h | 7 +++++-- src/utl/test.h | 11 ++++++++--- 12 files changed, 94 insertions(+), 89 deletions(-) create mode 100644 src/dev/deque.h diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 8af3ec2..4b230da 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -172,10 +172,6 @@ static struct CMC_DEF_ENTRY(SNAME) * \ CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ - static struct CMC_DEF_ITER(SNAME) \ - CMC_(PFX, _impl_it_start)(struct SNAME * _set_); \ - static struct CMC_DEF_ITER(SNAME) \ - CMC_(PFX, _impl_it_end)(struct SNAME * _set_); \ \ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ struct CMC_DEF_FVAL(SNAME) * f_val) \ diff --git a/src/cor/core.h b/src/cor/core.h index 68f6832..430d35d 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -22,6 +22,12 @@ #ifndef CMC_COR_CORE_H #define CMC_COR_CORE_H +#if defined(__GNUC__) || defined(__clang__) +#define CMC_UNUSED __attribute__((__unused__)) +#else +#define CMC_UNUSED +#endif + #include #include #include diff --git a/src/dev/deque.h b/src/dev/deque.h new file mode 100644 index 0000000..e69de29 diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 9106969..188a90c 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -361,18 +361,6 @@ /** * 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 }"; - #define CMC_EXT_CMC_DEQUE_STR(PARAMS) \ CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS) @@ -398,7 +386,18 @@ static const char *cmc_cmc_string_fmt_deque = "struct %s<%s> " { \ struct SNAME *d_ = _deque_; \ \ - return 0 <= fprintf(fptr, cmc_cmc_string_fmt_deque, \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "front:%" PRIuMAX ", " \ + "back:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, \ d_->buffer, d_->capacity, d_->count, d_->front, \ d_->back, d_->flag, d_->f_val, d_->alloc, \ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 3354a21..10ba62b 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -437,18 +437,6 @@ /** * 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 }"; - #define CMC_EXT_CMC_HASHMAP_STR(PARAMS) \ CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS) @@ -476,7 +464,18 @@ static const char *cmc_cmc_string_fmt_hashmap = "struct %s<%s, %s> " { \ struct SNAME *m_ = _map_; \ \ - return 0 <= fprintf(fptr, cmc_cmc_string_fmt_hashmap, \ + return 0 <= fprintf(fptr, \ + "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 }", \ 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, \ diff --git a/src/ext/cmc/hashmultimap.h b/src/ext/cmc/hashmultimap.h index 51c8436..3730f45 100644 --- a/src/ext/cmc/hashmultimap.h +++ b/src/ext/cmc/hashmultimap.h @@ -379,18 +379,6 @@ /** * STR */ -static const char *cmc_cmc_string_fmt_hashmultimap = "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 }"; - #define CMC_EXT_CMC_HASHMULTIMAP_STR(PARAMS) \ CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) @@ -418,7 +406,18 @@ static const char *cmc_cmc_string_fmt_hashmultimap = "struct %s<%s, %s> " { \ struct SNAME *m_ = _map_; \ \ - return 0 <= fprintf(fptr, cmc_cmc_string_fmt_hashmultimap, \ + return 0 <= fprintf(fptr, \ + "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 }", \ 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, \ diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h index c2d10c5..518eea0 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext/cmc/hashmultiset.h @@ -345,19 +345,6 @@ /** * STR */ -static const char *cmc_cmc_string_fmt_hashmultiset = - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "cardinality:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - #define CMC_EXT_CMC_HASHMULTISET_STR(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(PARAMS) @@ -383,7 +370,18 @@ static const char *cmc_cmc_string_fmt_hashmultiset = { \ struct SNAME *s_ = _set_; \ \ - return 0 <= fprintf(fptr, cmc_cmc_string_fmt_hashmultiset, \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "cardinality:%" PRIuMAX ", " \ + "load:%lf, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, \ s_->buffer, s_->capacity, s_->count, \ s_->cardinality, s_->load, s_->flag, s_->f_val, \ diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h index 344738c..933ce46 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext/cmc/hashset.h @@ -336,17 +336,6 @@ /** * STR */ -static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p }"; - #define CMC_EXT_CMC_HASHSET_STR(PARAMS) \ CMC_EXT_CMC_HASHSET_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HASHSET_STR_SOURCE(PARAMS) @@ -372,7 +361,17 @@ static const char *cmc_cmc_string_fmt_hashset = "struct %s<%s> " { \ struct SNAME *s_ = _set_; \ \ - return 0 <= fprintf(fptr, cmc_cmc_string_fmt_hashset, \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "load:%lf, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks: %p }", \ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, \ s_->buffer, s_->capacity, s_->count, s_->load, \ s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ diff --git a/src/ext/cmc/heap.h b/src/ext/cmc/heap.h index bc98c8d..33d8cc1 100644 --- a/src/ext/cmc/heap.h +++ b/src/ext/cmc/heap.h @@ -253,17 +253,6 @@ /** * STR */ -static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "type:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p}"; - #define CMC_EXT_CMC_HEAP_STR(PARAMS) \ CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) @@ -290,7 +279,17 @@ static const char *cmc_cmc_string_fmt_heap = "struct %s<%s> " struct SNAME *h_ = _heap_; \ const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \ \ - return 0 <= fprintf(fptr, cmc_cmc_string_fmt_heap, \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "type:%s, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks: %p}", \ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, \ h_->buffer, h_->capacity, h_->count, t, h_->flag, \ h_->f_val, h_->alloc, h_->callbacks); \ diff --git a/src/utl/assert.h b/src/utl/assert.h index 0d3a844..c63883c 100644 --- a/src/utl/assert.h +++ b/src/utl/assert.h @@ -56,6 +56,8 @@ #include #include +#include "../cor/core.h" + #define CMC_ASSERT_GLUE_(dtype, assertion) cmc_assert_##assertion##_##dtype #define CMC_ASSERT_GLUE(dtype, assertion) CMC_ASSERT_GLUE_(dtype, assertion) @@ -68,21 +70,21 @@ * This variable is also used in test.h utility to automatically pass or fail a * unit test. Once the unit test finishes, this variable is set back to true. */ -static bool cmc_assert_state = true; +CMC_UNUSED static bool cmc_assert_state = true; /** * cmc_assert_total * * Tracks the total calls to any type of assertion. */ -static uintmax_t cmc_assert_total = 0; +CMC_UNUSED static uintmax_t cmc_assert_total = 0; /** * cmc_assert_failed * * Tracks the total failed assertions. */ -static uintmax_t cmc_assert_failed = 0; +CMC_UNUSED static uintmax_t cmc_assert_failed = 0; /** * expression : An expression that is expected to be evaluated to true. diff --git a/src/utl/log.h b/src/utl/log.h index eada5f5..6027ee3 100644 --- a/src/utl/log.h +++ b/src/utl/log.h @@ -64,6 +64,8 @@ #include #include +#include "../cor/core.h" + static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" }; @@ -106,8 +108,9 @@ static struct #define cmc_log_fatal(fmt, ...) \ cmc_log(CMC_LOG_FATAL, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) -static void cmc_log(enum cmc_log_type log, const char *filename, - const char *funcname, unsigned line, const char *fmt, ...) +CMC_UNUSED static void cmc_log(enum cmc_log_type log, const char *filename, + const char *funcname, unsigned line, + const char *fmt, ...) { if (!cmc_log_config.enabled) return; diff --git a/src/utl/test.h b/src/utl/test.h index 7111421..be7b76f 100644 --- a/src/utl/test.h +++ b/src/utl/test.h @@ -42,6 +42,7 @@ #include #include +#include "../cor/core.h" #include "assert.h" #include "timer.h" @@ -56,9 +57,9 @@ struct cmc_test_info bool verbose; }; +#ifdef CMC_TEST_COLOR static inline const char *cmc_test_color(int i) { -#ifdef CMC_TEST_COLOR // 0 - Default, all off // 1 - Failed (red) // 2 - Passed (green) @@ -70,13 +71,17 @@ static inline const char *cmc_test_color(int i) }; return cmc_test_colors[i]; #else +static inline const char *cmc_test_color(int i) +{ + (void)i; return ""; #endif } /* Logging function */ -static void cmc_test_log(const char *unit_name, const char *current_test, - bool aborted, bool passed) +CMC_UNUSED static void cmc_test_log(const char *unit_name, + const char *current_test, bool aborted, + bool passed) { if (aborted) { From 97f46b3a818198af493771e6eaac7bc87b36ecc6 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 2 Jun 2020 15:20:34 -0300 Subject: [PATCH 18/51] More stuff moved to EXT --- src/cmc/intervalheap.h | 432 ++++++++----------------------------- src/ext/cmc/intervalheap.h | 320 +++++++++++++++++++++++++++ src/macro_collections.h | 1 + tests/to_string.c | 36 +++- 4 files changed, 443 insertions(+), 346 deletions(-) create mode 100644 src/ext/cmc/intervalheap.h diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index a1e23ea..0c05769 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -26,21 +26,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * IntervalHeap specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "size:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core IntervalHeap implementation */ @@ -59,133 +44,93 @@ static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Heap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ - V (*buffer)[2]; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of pairs of values in the array */ \ - size_t size; \ - \ - /* Current amount of elements in the heap */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Heap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target heap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _heap_); \ - void CMC_(PFX, _free)(struct SNAME * _heap_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _remove_max)(struct SNAME * _heap_); \ - bool CMC_(PFX, _remove_min)(struct SNAME * _heap_); \ - /* Collection Update */ \ - bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value); \ - /* Element Access */ \ - V CMC_(PFX, _max)(struct SNAME * _heap_); \ - V CMC_(PFX, _min)(struct SNAME * _heap_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ - bool CMC_(PFX, _full)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ - int CMC_(PFX, _flag)(struct SNAME * _heap_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_); \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* IntervalHeap Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ + V (*buffer)[2]; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of pairs of values in the array */ \ + size_t size; \ + \ + /* Current amount of elements in the heap */ \ + size_t count; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ + \ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ + \ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ + \ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ + \ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ + \ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _heap_); \ + void CMC_(PFX, _free)(struct SNAME * _heap_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _remove_max)(struct SNAME * _heap_); \ + bool CMC_(PFX, _remove_min)(struct SNAME * _heap_); \ + /* Collection Update */ \ + bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value); \ + /* Element Access */ \ + V CMC_(PFX, _max)(struct SNAME * _heap_); \ + V CMC_(PFX, _min)(struct SNAME * _heap_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ + bool CMC_(PFX, _full)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ + int CMC_(PFX, _flag)(struct SNAME * _heap_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); /* ------------------------------------------------------------------------- * Source @@ -754,209 +699,6 @@ static const char *cmc_cmc_string_fmt_intervalheap = "struct %s<%s> " return true; \ } \ \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _heap_) \ - { \ - struct cmc_string str; \ - struct SNAME *h_ = _heap_; \ - \ - int n = snprintf(str.s, cmc_string_len, \ - cmc_cmc_string_fmt_intervalheap, #SNAME, #V, h_, \ - h_->buffer, h_->capacity, h_->size, h_->count, \ - h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - if (iter->end) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } \ - \ static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_) \ { \ size_t index = _heap_->size - 1; \ diff --git a/src/ext/cmc/intervalheap.h b/src/ext/cmc/intervalheap.h new file mode 100644 index 0000000..a5d5992 --- /dev/null +++ b/src/ext/cmc/intervalheap.h @@ -0,0 +1,320 @@ +/** + * ext/cmc/intervalheap.h + * + * Creation Date: 02/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_INTERVALHEAP_H +#define CMC_EXT_CMC_INTERVALHEAP_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC IntervalHeap. + */ +#define CMC_EXT_CMC_INTERVALHEAP_PARTS ITER, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_INTERVALHEAP_ITER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* IntervalHeap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target IntervalHeap */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor++; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor--; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ + \ + if (iter->end) \ + return false; \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor += steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor < steps) \ + return false; \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor -= steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_INTERVALHEAP_STR(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ + { \ + struct SNAME *h_ = _heap_; \ + \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "size:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, \ + h_->buffer, h_->capacity, h_->size, h_->count, \ + h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \ + return false; \ + \ + if (i + 1 < _heap_->count) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_INTERVALHEAP_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index a49ba68..730561d 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -59,6 +59,7 @@ #include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */ #include "ext/cmc/hashset.h" /* Added in 31/05/2020 */ #include "ext/cmc/heap.h" /* Added in 01/06/2020 */ +#include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/to_string.c b/tests/to_string.c index 3c0365c..74357d4 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -9,6 +9,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h, heap, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih, intervalheap, , , int)) struct { @@ -33,6 +34,7 @@ int main(void) struct hashset *hs = hs_new(100, 0.6, (struct hashset_fval *)&int_ftab); struct heap *h = h_new(100, CMC_MAX_HEAP, (struct heap_fval *)&int_ftab); + struct intervalheap *ih = ih_new(100, (struct intervalheap_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -46,8 +48,35 @@ int main(void) hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); h_to_string(h, stdout); h_print(h, stdout, "\n[ ", ", ", " ]\n"); + ih_to_string(ih, stdout); + ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); - for (int i = 0; i < 20; i++) + fprintf(stdout, "\n"); + + d_push_back(d, 0); + hm_insert(hm, 0, 0); + hmm_insert(hmm, 0, 0); + hms_insert(hms, 0); + hs_insert(hs, 0); + h_insert(h, 0); + ih_insert(ih, 0); + + d_to_string(d, stdout); + d_print(d, stdout, "\n[ ", ", ", " ]\n"); + hm_to_string(hm, stdout); + hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hmm_to_string(hmm, stdout); + hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hms_to_string(hms, stdout); + hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); + hs_to_string(hs, stdout); + hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); + h_to_string(h, stdout); + h_print(h, stdout, "\n[ ", ", ", " ]\n"); + ih_to_string(ih, stdout); + ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); + + for (int i = 1; i < 20; i++) { d_push_back(d, i); hm_insert(hm, i, i); @@ -55,6 +84,7 @@ int main(void) hms_insert(hms, i); hs_insert(hs, i); h_insert(h, i); + ih_insert(ih, i); } fprintf(stdout, "\n"); @@ -71,12 +101,16 @@ int main(void) hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); h_to_string(h, stdout); h_print(h, stdout, "\n[ ", ", ", " ]\n"); + ih_to_string(ih, stdout); + ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm); hmm_free(hmm); hms_free(hms); hs_free(hs); + h_free(h); + ih_free(ih); } // clang-format on From 63eb52540699341729fff620a89104d146a0ab3c Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 3 Jun 2020 18:38:49 -0300 Subject: [PATCH 19/51] Moving more things to EXT --- src/cmc/hashmultiset.h | 299 +----- src/cmc/hashset.h | 465 ++------- src/cmc/linkedlist.h | 1680 +++++++++++---------------------- src/ext/cmc/hashmultiset.h | 318 ++++++- src/ext/cmc/hashset.h | 294 +++++- src/ext/cmc/linkedlist.h | 607 ++++++++++++ src/macro_collections.h | 1 + tests/main/src/intervalheap.c | 20 - tests/main/src/linkedlist.c | 22 - tests/to_string.c | 10 + 10 files changed, 1902 insertions(+), 1814 deletions(-) create mode 100644 src/ext/cmc/linkedlist.h diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index daaa563..91d80de 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -161,28 +161,7 @@ /* Collection Utility */ \ bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ - \ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source @@ -810,282 +789,6 @@ return true; \ } \ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - size_t max_ = m1 > m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ - size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ - size_t max_ = m1 > m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct SNAME *_set_A_ = \ - _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \ - size_t max_ = m1 < m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert_many) \ - (_set_r_, CMC_(PFX, _iter_value)(&iter1), \ - CMC_(PFX, _iter_multiplicity)(&iter1)); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert_many) \ - (_set_r_, CMC_(PFX, _iter_value)(&iter2), \ - CMC_(PFX, _iter_multiplicity)(&iter2)); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 != m2) \ - { \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - else \ - CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ - } \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ - size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ - \ - if (m1 != m2) \ - { \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - else \ - CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ - } \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - if (_set1_->count > _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 > m2) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ - \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - if (_set1_->count >= _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - else \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 >= m2) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ - \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, \ V value) \ { \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 4b230da..08ac2af 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -47,121 +47,102 @@ /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Hashset Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ - \ - /* Current Array Capcity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry value */ \ - V value; \ - \ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ - \ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _set_); \ - void CMC_(PFX, _free)(struct SNAME * _set_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _set_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _set_); \ - bool CMC_(PFX, _full)(struct SNAME * _set_); \ - size_t CMC_(PFX, _count)(struct SNAME * _set_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ - double CMC_(PFX, _load)(struct SNAME * _set_); \ - int CMC_(PFX, _flag)(struct SNAME * _set_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ - \ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); +#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Hashset Structure */ \ + struct SNAME \ + { \ + /* Array of Entries */ \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ + \ + /* Current Array Capcity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry value */ \ + V value; \ + \ + /* The distance of this node to its original position, used by */ \ + /* robin-hood hashing */ \ + size_t dist; \ + \ + /* The sate of this node (DELETED, EMPTY, FILLED) */ \ + enum cmc_entry_state state; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ + \ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ + \ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ + \ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ + \ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ + \ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _set_); \ + void CMC_(PFX, _free)(struct SNAME * _set_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _set_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _set_); \ + bool CMC_(PFX, _full)(struct SNAME * _set_); \ + size_t CMC_(PFX, _count)(struct SNAME * _set_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ + double CMC_(PFX, _load)(struct SNAME * _set_); \ + int CMC_(PFX, _flag)(struct SNAME * _set_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source @@ -669,260 +650,6 @@ return true; \ } \ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - /* TODO turn this into a normal loop and check for errors */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct SNAME *_set_A_ = \ - _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - /* Is _set1_ a subset of _set2_ ? */ \ - /* A set X is a subset of a set Y when: X <= Y */ \ - /* If X is a subset of Y, then Y is a superset of X */ \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - /* If the cardinality of _set1_ is greater than that of _set2_, */ \ - /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ - if (_set1_->count > _set2_->count) \ - return false; \ - \ - /* The empty set is a subset of all sets */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - /* Is _set1_ a superset of _set2_ ? */ \ - /* A set X is a superset of a set Y when: X >= Y */ \ - /* If X is a superset of Y, then Y is a subset of X */ \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ - \ - /* Is _set1_ a proper subset of _set2_ ? */ \ - /* A set X is a proper subset of a set Y when: X < Y */ \ - /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - /* If the cardinality of _set1_ is greater than or equal to that of */ \ - /* _set2_, then it is safe to say that _set1_ can't be a proper */ \ - /* subset of _set2_ */ \ - if (_set1_->count >= _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - /* The empty set is a proper subset of all non-empty sets */ \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - /* The empty set is not a proper subset of itself (this is true */ \ - /* for any set) */ \ - else \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - /* Is _set1_ a proper superset of _set2_ ? */ \ - /* A set X is a proper superset of a set Y when: X > Y */ \ - /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ - \ - /* Is _set1_ a disjointset of _set2_ ? */ \ - /* A set X is a disjointset of a set Y if their intersection is empty, */ \ - /* that is, if there are no elements in common between the two */ \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - /* The intersection of an empty set with any other set will result */ \ - /* in an empty set */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ static struct CMC_DEF_ENTRY(SNAME) * \ CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ { \ diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index 7d76647..b332033 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -33,20 +33,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * LinkedList specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_linkedlist = "struct %s<%s> " - "at %p { " - "count:%" PRIuMAX ", " - "head:%p, " - "tail:%p, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core LinkedList implementation */ @@ -65,1099 +51,587 @@ static const char *cmc_cmc_string_fmt_linkedlist = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Linked List Structure */ \ - struct SNAME \ - { \ - /* First node in the list */ \ - struct CMC_DEF_NODE(SNAME) * head; \ - \ - /* Last node in the list */ \ - struct CMC_DEF_NODE(SNAME) * tail; \ - \ - /* Current amount of elements in the list */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Doubly-linked list node */ \ - struct CMC_DEF_NODE(SNAME) \ - { \ - /* Node's value */ \ - V value; \ - \ - /* Pointer to the next node on the linked list */ \ - struct CMC_DEF_NODE(SNAME) * next; \ - \ - /* Pointer to the previous node on the linked list */ \ - struct CMC_DEF_NODE(SNAME) * prev; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Linked List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target Linked List */ \ - struct SNAME *target; \ - \ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ - V CMC_(PFX, _back)(struct SNAME * _list_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \ - \ - /* Node Related Functions */ \ - /* Node Allocation and Deallocation */ \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \ - void CMC_(PFX, _free_node)(struct SNAME * _list_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - /* Node Access Relative to a Linked List */ \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \ - /* Input and Output Relative to a Node */ \ - bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value); \ - bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value); \ - bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - /* Node Access Relative to a Linked List Node */ \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* Linked List Structure */ \ + struct SNAME \ + { \ + /* First node in the list */ \ + struct CMC_DEF_NODE(SNAME) * head; \ + \ + /* Last node in the list */ \ + struct CMC_DEF_NODE(SNAME) * tail; \ + \ + /* Current amount of elements in the list */ \ + size_t count; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Doubly-linked list node */ \ + struct CMC_DEF_NODE(SNAME) \ + { \ + /* Node's value */ \ + V value; \ + \ + /* Pointer to the next node on the linked list */ \ + struct CMC_DEF_NODE(SNAME) * next; \ + \ + /* Pointer to the previous node on the linked list */ \ + struct CMC_DEF_NODE(SNAME) * prev; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ + \ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ + \ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ + \ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ + \ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ + \ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ + V CMC_(PFX, _back)(struct SNAME * _list_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - if (!f_val) \ - return NULL; \ - \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = NULL; \ - \ - return _list_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = callbacks; \ - \ - return _list_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (_list_->head != NULL) \ - { \ - _list_->head = _list_->head->next; \ - \ - if (_list_->f_val->free) \ - { \ - _list_->f_val->free(scan->value); \ - } \ - \ - _list_->alloc->free(scan); \ - \ - scan = _list_->head; \ - } \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - CMC_(PFX, _clear)(_list_); \ - \ - _list_->alloc->free(_list_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _list_->alloc = &cmc_alloc_node_default; \ - else \ - _list_->alloc = alloc; \ - \ - _list_->callbacks = callbacks; \ - \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->head = _node_; \ - _list_->tail = _node_; \ - } \ - else \ - { \ - _node_->next = _list_->head; \ - _list_->head->prev = _node_; \ - _list_->head = _node_; \ - } \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ - { \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - { \ - return CMC_(PFX, _push_front)(_list_, value); \ - } \ - else if (index == _list_->count) \ - { \ - return CMC_(PFX, _push_back)(_list_, value); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index - 1); \ - \ - _node_->next = scan->next; \ - _node_->prev = scan; \ - _node_->next->prev = _node_; \ - _node_->prev->next = _node_; \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->head = _node_; \ - _list_->tail = _node_; \ - } \ - else \ - { \ - _node_->prev = _list_->tail; \ - _list_->tail->next = _node_; \ - _list_->tail = _node_; \ - } \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \ - _list_->head = _list_->head->next; \ - \ - _list_->alloc->free(_node_); \ - \ - if (_list_->head == NULL) \ - _list_->tail = NULL; \ - else \ - _list_->head->prev = NULL; \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - { \ - return CMC_(PFX, _pop_front)(_list_); \ - } \ - else if (index == _list_->count - 1) \ - { \ - return CMC_(PFX, _pop_back)(_list_); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (!_node_) \ - return false; \ - \ - _node_->next->prev = _node_->prev; \ - _node_->prev->next = _node_->next; \ - \ - _list_->alloc->free(_node_); \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \ - _list_->tail = _list_->tail->prev; \ - \ - _list_->alloc->free(_node_); \ - \ - if (_list_->tail == NULL) \ - _list_->head = NULL; \ - else \ - _list_->tail->next = NULL; \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->head->value; \ - } \ - \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (scan == NULL) \ - return (V){ 0 }; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return scan->value; \ - } \ - \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (scan == NULL) \ - return NULL; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return &(scan->value); \ - } \ - \ - V CMC_(PFX, _back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->tail->value; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - if (_list_->f_val->cmp(scan->value, value) == 0) \ - { \ - result = true; \ - break; \ - } \ - \ - scan = scan->next; \ - } \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _list_->f_val, _list_->alloc, _list_->callbacks); \ - \ - if (!result) \ - return NULL; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - /* This allocation should never fail since it might not be */ \ - /* possible to recover from it. That is why it isn't checked */ \ - struct CMC_DEF_NODE(SNAME) * new_node; \ - \ - if (_list_->f_val->cpy) \ - new_node = CMC_(PFX, _new_node)( \ - _list_, _list_->f_val->cpy(scan->value)); \ - else \ - new_node = CMC_(PFX, _new_node)(_list_, scan->value); \ - \ - if (!result->head) \ - { \ - result->head = new_node; \ - result->tail = new_node; \ - } \ - else \ - { \ - new_node->prev = result->tail; \ - result->tail->next = new_node; \ - result->tail = new_node; \ - } \ - \ - scan = scan->next; \ - } \ - \ - result->count = _list_->count; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - _list1_->flag = CMC_FLAG_OK; \ - _list2_->flag = CMC_FLAG_OK; \ - \ - if (_list1_->count != _list2_->count) \ - return false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \ - struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \ - \ - while (scan1 != NULL && scan2 != NULL) \ - { \ - if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \ - return false; \ - \ - scan1 = scan1->next; \ - scan2 = scan2->next; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ - { \ - struct cmc_string str; \ - struct SNAME *l_ = _list_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_linkedlist, \ - #SNAME, #V, l_, l_->count, l_->head, l_->tail, \ - l_->flag, l_->f_val, l_->alloc, l_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - if (!_list_->f_val->str(fptr, scan->value)) \ - return false; \ - \ - scan = scan->next; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ - \ - if (!_node_) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - _node_->value = value; \ - _node_->next = NULL; \ - _node_->prev = NULL; \ - \ - return _node_; \ - } \ - \ - void CMC_(PFX, _free_node)(struct SNAME * _list_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - _list_->alloc->free(_node_); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \ - { \ - return _list_->head; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \ - \ - if (index <= _list_->count / 2) \ - { \ - _node_ = _list_->head; \ - for (size_t i = 0; i < index; i++) \ - { \ - _node_ = _node_->next; \ - } \ - } \ - else \ - { \ - _node_ = _list_->tail; \ - for (size_t i = _list_->count - 1; i > index; i--) \ - { \ - _node_ = _node_->prev; \ - } \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - return _node_; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \ - { \ - return _list_->tail; \ - } \ - \ - bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *new_node = \ - CMC_(PFX, _new_node)(_owner_, value); \ - \ - if (!new_node) \ - return false; \ - \ - new_node->next = _node_->next; \ - \ - if (_node_->next != NULL) \ - _node_->next->prev = new_node; \ - else \ - _owner_->tail = new_node; \ - \ - new_node->prev = _node_; \ - _node_->next = new_node; \ - \ - _owner_->count++; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *new_node = \ - CMC_(PFX, _new_node)(_owner_, value); \ - \ - if (!new_node) \ - return false; \ - \ - new_node->prev = _node_->prev; \ - \ - if (_node_->prev != NULL) \ - _node_->prev->next = new_node; \ - else \ - _owner_->head = new_node; \ - \ - new_node->next = _node_; \ - _node_->prev = new_node; \ - \ - _owner_->count++; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->next == NULL) \ - { \ - _owner_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \ - \ - _node_->next = _node_->next->next; \ - \ - if (tmp->next != NULL) \ - tmp->next->prev = _node_; \ - else \ - _owner_->tail = _node_; \ - \ - _owner_->alloc->free(tmp); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->prev != NULL) \ - _node_->prev->next = _node_->next; \ - else \ - _owner_->head = _node_->next; \ - \ - if (_node_->next != NULL) \ - _node_->next->prev = _node_->prev; \ - else \ - _owner_->tail = _node_->prev; \ - \ - _owner_->alloc->free(_node_); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->prev == NULL) \ - { \ - _owner_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \ - \ - _node_->prev = _node_->prev->prev; \ - \ - if (tmp->prev != NULL) \ - tmp->prev->next = _node_; \ - else \ - _owner_->head = _node_; \ - \ - _owner_->alloc->free(tmp); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - return _node_->next; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - return _node_->prev; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->head; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->tail; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.index = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->head; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->tail; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor->next == NULL) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = iter->cursor->next; \ - iter->index++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor->prev == NULL) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = iter->cursor->prev; \ - iter->index--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor->next == NULL) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index += steps; \ - \ - for (size_t i = 0; i < steps; i++) \ - iter->cursor = iter->cursor->next; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor->prev == NULL) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index -= steps; \ - \ - for (size_t i = 0; i < steps; i++) \ - iter->cursor = iter->cursor->prev; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->cursor->value; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->cursor->value); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ +#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ + \ + /* Implementation Detail Functions */ \ + /* None */ \ + \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + if (!f_val) \ + return NULL; \ + \ + struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ + \ + struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_list_) \ + return NULL; \ + \ + _list_->count = 0; \ + _list_->head = NULL; \ + _list_->tail = NULL; \ + _list_->flag = CMC_FLAG_OK; \ + _list_->f_val = f_val; \ + _list_->alloc = alloc; \ + _list_->callbacks = NULL; \ + \ + return _list_; \ + } \ + \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + if (!f_val) \ + return NULL; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ + \ + if (!_list_) \ + return NULL; \ + \ + _list_->count = 0; \ + _list_->head = NULL; \ + _list_->tail = NULL; \ + _list_->flag = CMC_FLAG_OK; \ + _list_->f_val = f_val; \ + _list_->alloc = alloc; \ + _list_->callbacks = callbacks; \ + \ + return _list_; \ + } \ + \ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ + \ + while (_list_->head != NULL) \ + { \ + _list_->head = _list_->head->next; \ + \ + if (_list_->f_val->free) \ + { \ + _list_->f_val->free(scan->value); \ + } \ + \ + _list_->alloc->free(scan); \ + \ + scan = _list_->head; \ + } \ + \ + _list_->count = 0; \ + _list_->head = NULL; \ + _list_->tail = NULL; \ + _list_->flag = CMC_FLAG_OK; \ + } \ + \ + void CMC_(PFX, _free)(struct SNAME * _list_) \ + { \ + CMC_(PFX, _clear)(_list_); \ + \ + _list_->alloc->free(_list_); \ + } \ + \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks) \ + { \ + if (!alloc) \ + _list_->alloc = &cmc_alloc_node_default; \ + else \ + _list_->alloc = alloc; \ + \ + _list_->callbacks = callbacks; \ + \ + _list_->flag = CMC_FLAG_OK; \ + } \ + \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ + \ + if (!_node_) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->head = _node_; \ + _list_->tail = _node_; \ + } \ + else \ + { \ + _node_->next = _list_->head; \ + _list_->head->prev = _node_; \ + _list_->head = _node_; \ + } \ + \ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ + { \ + if (index > _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ + \ + if (index == 0) \ + { \ + return CMC_(PFX, _push_front)(_list_, value); \ + } \ + else if (index == _list_->count) \ + { \ + return CMC_(PFX, _push_back)(_list_, value); \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ + \ + if (!_node_) \ + return false; \ + \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index - 1); \ + \ + _node_->next = scan->next; \ + _node_->prev = scan; \ + _node_->next->prev = _node_; \ + _node_->prev->next = _node_; \ + \ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _new_node)(_list_, value); \ + \ + if (!_node_) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->head = _node_; \ + _list_->tail = _node_; \ + } \ + else \ + { \ + _node_->prev = _list_->tail; \ + _list_->tail->next = _node_; \ + _list_->tail = _node_; \ + } \ + \ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \ + _list_->head = _list_->head->next; \ + \ + _list_->alloc->free(_node_); \ + \ + if (_list_->head == NULL) \ + _list_->tail = NULL; \ + else \ + _list_->head->prev = NULL; \ + \ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ + \ + if (index == 0) \ + { \ + return CMC_(PFX, _pop_front)(_list_); \ + } \ + else if (index == _list_->count - 1) \ + { \ + return CMC_(PFX, _pop_back)(_list_); \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + CMC_(PFX, _get_node)(_list_, index); \ + \ + if (!_node_) \ + return false; \ + \ + _node_->next->prev = _node_->prev; \ + _node_->prev->next = _node_->next; \ + \ + _list_->alloc->free(_node_); \ + \ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \ + _list_->tail = _list_->tail->prev; \ + \ + _list_->alloc->free(_node_); \ + \ + if (_list_->tail == NULL) \ + _list_->head = NULL; \ + else \ + _list_->tail->next = NULL; \ + \ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _front)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return _list_->head->value; \ + } \ + \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return (V){ 0 }; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index); \ + \ + if (scan == NULL) \ + return (V){ 0 }; \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return scan->value; \ + } \ + \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return NULL; \ + } \ + \ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *scan = \ + CMC_(PFX, _get_node)(_list_, index); \ + \ + if (scan == NULL) \ + return NULL; \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return &(scan->value); \ + } \ + \ + V CMC_(PFX, _back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return _list_->tail->value; \ + } \ + \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ + { \ + _list_->flag = CMC_FLAG_OK; \ + \ + bool result = false; \ + \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ + \ + while (scan != NULL) \ + { \ + if (_list_->f_val->cmp(scan->value, value) == 0) \ + { \ + result = true; \ + break; \ + } \ + \ + scan = scan->next; \ + } \ + \ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ + { \ + return _list_->count == 0; \ + } \ + \ + size_t CMC_(PFX, _count)(struct SNAME * _list_) \ + { \ + return _list_->count; \ + } \ + \ + int CMC_(PFX, _flag)(struct SNAME * _list_) \ + { \ + return _list_->flag; \ + } \ + \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + _list_->f_val, _list_->alloc, _list_->callbacks); \ + \ + if (!result) \ + return NULL; \ + \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ + \ + while (scan != NULL) \ + { \ + /* This allocation should never fail since it might not be */ \ + /* possible to recover from it. That is why it isn't checked */ \ + struct CMC_DEF_NODE(SNAME) * new_node; \ + \ + if (_list_->f_val->cpy) \ + new_node = CMC_(PFX, _new_node)( \ + _list_, _list_->f_val->cpy(scan->value)); \ + else \ + new_node = CMC_(PFX, _new_node)(_list_, scan->value); \ + \ + if (!result->head) \ + { \ + result->head = new_node; \ + result->tail = new_node; \ + } \ + else \ + { \ + new_node->prev = result->tail; \ + result->tail->next = new_node; \ + result->tail = new_node; \ + } \ + \ + scan = scan->next; \ + } \ + \ + result->count = _list_->count; \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + return result; \ + } \ + \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ + { \ + _list1_->flag = CMC_FLAG_OK; \ + _list2_->flag = CMC_FLAG_OK; \ + \ + if (_list1_->count != _list2_->count) \ + return false; \ + \ + struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \ + struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \ + \ + while (scan1 != NULL && scan2 != NULL) \ + { \ + if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \ + return false; \ + \ + scan1 = scan1->next; \ + scan2 = scan2->next; \ + } \ + \ + return true; \ } #endif /* CMC_CMC_LINKEDLIST_H */ diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h index 518eea0..af1b848 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext/cmc/hashmultiset.h @@ -16,7 +16,7 @@ /** * All the EXT parts of CMC HashMultiSet. */ -#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, STR +#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, SETF, STR /** * ITER @@ -342,6 +342,322 @@ return iter->index; \ } +/** + * SETF + */ +#define CMC_EXT_CMC_HASHMULTISET_SETF(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) + +#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(PFX, SNAME, V) \ + \ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); + +#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(PFX, SNAME, V) \ + \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + size_t max_ = m1 > m2 ? m1 : m2; \ + \ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ + \ + size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ + size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ + size_t max_ = m1 > m2 ? m1 : m2; \ + \ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + \ + struct SNAME *_set_A_ = \ + _set1_->count < _set2_->count ? _set1_ : _set2_; \ + struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \ + size_t max_ = m1 < m2 ? m1 : m2; \ + \ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + \ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + CMC_(PFX, _insert_many) \ + (_set_r_, CMC_(PFX, _iter_value)(&iter1), \ + CMC_(PFX, _iter_multiplicity)(&iter1)); \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + CMC_(PFX, _insert_many) \ + (_set_r_, CMC_(PFX, _iter_value)(&iter2), \ + CMC_(PFX, _iter_multiplicity)(&iter2)); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + return NULL; \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + \ + if (m1 != m2) \ + { \ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + else \ + CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ + } \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ + \ + size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ + size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ + \ + if (m1 != m2) \ + { \ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + else \ + CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ + } \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + if (_set1_->count > _set2_->count) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + \ + if (m1 > m2) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ + } \ + \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + if (_set1_->count >= _set2_->count) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_set1_)) \ + { \ + if (!CMC_(PFX, _empty)(_set2_)) \ + return true; \ + else \ + return false; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + \ + if (m1 >= m2) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ + } \ + \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ + return false; \ + } \ + \ + return true; \ + } + /** * STR */ diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h index 933ce46..cdb627e 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext/cmc/hashset.h @@ -16,7 +16,7 @@ /** * All the EXT parts of CMC HashSet. */ -#define CMC_EXT_CMC_HASHSET_PARTS ITER, STR +#define CMC_EXT_CMC_HASHSET_PARTS ITER, SETF, STR /** * ITER @@ -333,6 +333,298 @@ return iter->index; \ } +/** + * SETF + */ +#define CMC_EXT_CMC_HASHSET_SETF(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) + +#define CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_SETF_HEADER_(PFX, SNAME, V) \ + \ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_); + +#define CMC_EXT_CMC_HASHSET_SETF_SOURCE_(PFX, SNAME, V) \ + \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + /* TODO turn this into a normal loop and check for errors */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + struct SNAME *_set_A_ = \ + _set1_->count < _set2_->count ? _set1_ : _set2_; \ + struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ + _set1_->f_val, _set1_->alloc, NULL); \ + \ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); \ + CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter2); \ + CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ + \ + _set_r_->callbacks = _set1_->callbacks; \ + \ + return _set_r_; \ + } \ + \ + /* Is _set1_ a subset of _set2_ ? */ \ + /* A set X is a subset of a set Y when: X <= Y */ \ + /* If X is a subset of Y, then Y is a superset of X */ \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ + \ + /* If the cardinality of _set1_ is greater than that of _set2_, */ \ + /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ + if (_set1_->count > _set2_->count) \ + return false; \ + \ + /* The empty set is a subset of all sets */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + /* Is _set1_ a superset of _set2_ ? */ \ + /* A set X is a superset of a set Y when: X >= Y */ \ + /* If X is a superset of Y, then Y is a subset of X */ \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ + } \ + \ + /* Is _set1_ a proper subset of _set2_ ? */ \ + /* A set X is a proper subset of a set Y when: X < Y */ \ + /* If X is a proper subset of Y, then Y is a proper superset of X */ \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ + \ + /* If the cardinality of _set1_ is greater than or equal to that of */ \ + /* _set2_, then it is safe to say that _set1_ can't be a proper */ \ + /* subset of _set2_ */ \ + if (_set1_->count >= _set2_->count) \ + return false; \ + \ + if (CMC_(PFX, _empty)(_set1_)) \ + { \ + /* The empty set is a proper subset of all non-empty sets */ \ + if (!CMC_(PFX, _empty)(_set2_)) \ + return true; \ + /* The empty set is not a proper subset of itself (this is true */ \ + /* for any set) */ \ + else \ + return false; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + return false; \ + } \ + \ + return true; \ + } \ + \ + /* Is _set1_ a proper superset of _set2_ ? */ \ + /* A set X is a proper superset of a set Y when: X > Y */ \ + /* If X is a proper superset of Y, then Y is a proper subset of X */ \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ + } \ + \ + /* Is _set1_ a disjointset of _set2_ ? */ \ + /* A set X is a disjointset of a set Y if their intersection is empty, */ \ + /* that is, if there are no elements in common between the two */ \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ + struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ + \ + /* The intersection of an empty set with any other set will result */ \ + /* in an empty set */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ + \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ + \ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ + return false; \ + } \ + \ + return true; \ + } + /** * STR */ diff --git a/src/ext/cmc/linkedlist.h b/src/ext/cmc/linkedlist.h new file mode 100644 index 0000000..15d1f3a --- /dev/null +++ b/src/ext/cmc/linkedlist.h @@ -0,0 +1,607 @@ +/** + * ext/cmc/linkedlist.h + * + * Creation Date: 26/05/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_LINKEDLIST_H +#define CMC_EXT_CMC_LINKEDLIST_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC LinkedList. + */ +#define CMC_EXT_CMC_LINKEDLIST_PARTS ITER, NODE, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_LINKEDLIST_ITER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* LinkedList Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target Linked List */ \ + struct SNAME *target; \ + \ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ + \ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = target->head; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = target->tail; \ + iter.index = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + iter.index = target->count - 1; \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->head; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->tail; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor->next == NULL) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor = iter->cursor->next; \ + iter->index++; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor->prev == NULL) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor = iter->cursor->prev; \ + iter->index--; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor->next == NULL) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->index += steps; \ + \ + for (size_t i = 0; i < steps; i++) \ + iter->cursor = iter->cursor->next; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor->prev == NULL) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->index < steps) \ + return false; \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->index -= steps; \ + \ + for (size_t i = 0; i < steps; i++) \ + iter->cursor = iter->cursor->prev; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->cursor->value; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->cursor->value); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ + } + +/** + * NODE + */ +#define CMC_EXT_CMC_LINKEDLIST_NODE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(PFX, SNAME, V) \ + \ + /* Node Allocation and Deallocation */ \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \ + void CMC_(PFX, _free_node)(struct SNAME * _list_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + /* Node Access Relative to a Linked List */ \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \ + /* Input and Output Relative to a Node */ \ + bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value); \ + bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value); \ + bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_); \ + /* Node Access Relative to a Linked List Node */ \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_); + +#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = \ + _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ + \ + if (!_node_) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + _node_->value = value; \ + _node_->next = NULL; \ + _node_->prev = NULL; \ + \ + return _node_; \ + } \ + \ + void CMC_(PFX, _free_node)(struct SNAME * _list_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + _list_->alloc->free(_node_); \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \ + { \ + return _list_->head; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return NULL; \ + } \ + \ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \ + \ + if (index <= _list_->count / 2) \ + { \ + _node_ = _list_->head; \ + for (size_t i = 0; i < index; i++) \ + { \ + _node_ = _node_->next; \ + } \ + } \ + else \ + { \ + _node_ = _list_->tail; \ + for (size_t i = _list_->count - 1; i > index; i--) \ + { \ + _node_ = _node_->prev; \ + } \ + } \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + return _node_; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \ + { \ + return _list_->tail; \ + } \ + \ + bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *new_node = \ + CMC_(PFX, _new_node)(_owner_, value); \ + \ + if (!new_node) \ + return false; \ + \ + new_node->next = _node_->next; \ + \ + if (_node_->next != NULL) \ + _node_->next->prev = new_node; \ + else \ + _owner_->tail = new_node; \ + \ + new_node->prev = _node_; \ + _node_->next = new_node; \ + \ + _owner_->count++; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *new_node = \ + CMC_(PFX, _new_node)(_owner_, value); \ + \ + if (!new_node) \ + return false; \ + \ + new_node->prev = _node_->prev; \ + \ + if (_node_->prev != NULL) \ + _node_->prev->next = new_node; \ + else \ + _owner_->head = new_node; \ + \ + new_node->next = _node_; \ + _node_->prev = new_node; \ + \ + _owner_->count++; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->next == NULL) \ + { \ + _owner_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \ + \ + _node_->next = _node_->next->next; \ + \ + if (tmp->next != NULL) \ + tmp->next->prev = _node_; \ + else \ + _owner_->tail = _node_; \ + \ + _owner_->alloc->free(tmp); \ + \ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->prev != NULL) \ + _node_->prev->next = _node_->next; \ + else \ + _owner_->head = _node_->next; \ + \ + if (_node_->next != NULL) \ + _node_->next->prev = _node_->prev; \ + else \ + _owner_->tail = _node_->prev; \ + \ + _owner_->alloc->free(_node_); \ + \ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ + struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->prev == NULL) \ + { \ + _owner_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \ + \ + _node_->prev = _node_->prev->prev; \ + \ + if (tmp->prev != NULL) \ + tmp->prev->next = _node_; \ + else \ + _owner_->head = _node_; \ + \ + _owner_->alloc->free(tmp); \ + \ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ + \ + return true; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + return _node_->next; \ + } \ + \ + struct CMC_DEF_NODE(SNAME) * \ + CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + return _node_->prev; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_LINKEDLIST_STR(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ + { \ + struct SNAME *l_ = _list_; \ + \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "count:%" PRIuMAX ", " \ + "head:%p, " \ + "tail:%p, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, \ + l_->count, l_->head, l_->tail, l_->flag, \ + l_->f_val, l_->alloc, l_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ + \ + while (scan != NULL) \ + { \ + if (!_list_->f_val->str(fptr, scan->value)) \ + return false; \ + \ + scan = scan->next; \ + \ + if (scan) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_LINKEDLIST_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 730561d..6ad0562 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -60,6 +60,7 @@ #include "ext/cmc/hashset.h" /* Added in 31/05/2020 */ #include "ext/cmc/heap.h" /* Added in 01/06/2020 */ #include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */ +#include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index ddcce5b..62522f1 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -477,26 +477,6 @@ _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_) } return 1; } -struct cmc_string ih_to_string(struct intervalheap *_heap_) -{ - struct cmc_string str; - struct intervalheap *h_ = _heap_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_intervalheap, - "CMC_PARAM_SNAME((ih, intervalheap, , , size_t))", - "CMC_PARAM_V((ih, intervalheap, , , size_t))", h_, - h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, - h_->f_val, h_->alloc, h_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool ih_print(struct intervalheap *_heap_, FILE *fptr) -{ - for (size_t i = 0; i < _heap_->count; i++) - { - if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) - return 0; - } - return 1; -} struct intervalheap_iter ih_iter_start(struct intervalheap *target) { struct intervalheap_iter iter; diff --git a/tests/main/src/linkedlist.c b/tests/main/src/linkedlist.c index acf7384..2fe8dbd 100644 --- a/tests/main/src/linkedlist.c +++ b/tests/main/src/linkedlist.c @@ -446,28 +446,6 @@ _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) } return 1; } -struct cmc_string ll_to_string(struct linkedlist *_list_) -{ - struct cmc_string str; - struct linkedlist *l_ = _list_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_linkedlist, - "CMC_PARAM_SNAME((ll, linkedlist, , , size_t))", - "CMC_PARAM_V((ll, linkedlist, , , size_t))", l_, l_->count, - l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, - l_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool ll_print(struct linkedlist *_list_, FILE *fptr) -{ - struct linkedlist_node *scan = _list_->head; - while (scan != ((void *)0)) - { - if (!_list_->f_val->str(fptr, scan->value)) - return 0; - scan = scan->next; - } - return 1; -} struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) { struct linkedlist_node *_node_ = diff --git a/tests/to_string.c b/tests/to_string.c index 74357d4..1aad044 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -10,6 +10,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h, heap, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih, intervalheap, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int)) struct { @@ -35,6 +36,7 @@ int main(void) (struct hashset_fval *)&int_ftab); struct heap *h = h_new(100, CMC_MAX_HEAP, (struct heap_fval *)&int_ftab); struct intervalheap *ih = ih_new(100, (struct intervalheap_fval *)&int_ftab); + struct linkedlist *ll = ll_new((struct linkedlist_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -50,6 +52,8 @@ int main(void) h_print(h, stdout, "\n[ ", ", ", " ]\n"); ih_to_string(ih, stdout); ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); + ll_to_string(ll, stdout); + ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -60,6 +64,7 @@ int main(void) hs_insert(hs, 0); h_insert(h, 0); ih_insert(ih, 0); + ll_push_back(ll, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -75,6 +80,8 @@ int main(void) h_print(h, stdout, "\n[ ", ", ", " ]\n"); ih_to_string(ih, stdout); ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); + ll_to_string(ll, stdout); + ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -85,6 +92,7 @@ int main(void) hs_insert(hs, i); h_insert(h, i); ih_insert(ih, i); + ll_push_back(ll, i); } fprintf(stdout, "\n"); @@ -103,6 +111,8 @@ int main(void) h_print(h, stdout, "\n[ ", ", ", " ]\n"); ih_to_string(ih, stdout); ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); + ll_to_string(ll, stdout); + ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm); From 90a6b4ef0d89e1f30db0ac767da55e93da64df9f Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 3 Jun 2020 20:07:03 -0300 Subject: [PATCH 20/51] Hash CORE no longer depends on ITER and moved some other things to EXT --- src/cmc/deque.h | 16 ----- src/cmc/hashmap.h | 133 +++++++++++++++++++++--------------------- src/ext/cmc/deque.h | 106 +++++++++++++++++++-------------- src/ext/cmc/hashmap.h | 24 +++++++- 4 files changed, 150 insertions(+), 129 deletions(-) diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 4ade839..af92d11 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -120,7 +120,6 @@ struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ void CMC_(PFX, _clear)(struct SNAME * _deque_); \ void CMC_(PFX, _free)(struct SNAME * _deque_); \ - void CMC_(PFX, _release)(struct SNAME _deque_); \ /* Customization of Allocation and Callbacks */ \ void CMC_(PFX, _customize)(struct SNAME * _deque_, \ struct cmc_alloc_node * alloc, \ @@ -234,21 +233,6 @@ _deque_->alloc->free(_deque_); \ } \ \ - void CMC_(PFX, _release)(struct SNAME _deque_) \ - { \ - if (_deque_.f_val->free) \ - { \ - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ - { \ - _deque_.f_val->free(_deque_.buffer[i]); \ - \ - i = (i + 1) % _deque_.capacity; \ - } \ - } \ - \ - _deque_.alloc->free(_deque_.buffer); \ - } \ - \ void CMC_(PFX, _customize)(struct SNAME * _deque_, \ struct cmc_alloc_node * alloc, \ struct cmc_callbacks * callbacks) \ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index e768b2c..a122669 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -154,7 +154,6 @@ struct cmc_callbacks * callbacks); \ void CMC_(PFX, _clear)(struct SNAME * _map_); \ void CMC_(PFX, _free)(struct SNAME * _map_); \ - void CMC_(PFX, _release)(struct SNAME _map_); \ /* Customization of Allocation and Callbacks */ \ void CMC_(PFX, _customize)(struct SNAME * _map_, \ struct cmc_alloc_node * alloc, \ @@ -294,27 +293,6 @@ _map_->alloc->free(_map_); \ } \ \ - void CMC_(PFX, _release)(struct SNAME _map_) \ - { \ - if (_map_.f_key->free || _map_.f_val->free) \ - { \ - 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->free) \ - _map_.f_key->free(entry->key); \ - if (_map_.f_val->free) \ - _map_.f_val->free(entry->value); \ - } \ - } \ - } \ - \ - _map_.alloc->free(_map_.buffer); \ - } \ - \ void CMC_(PFX, _customize)(struct SNAME * _map_, \ struct cmc_alloc_node * alloc, \ struct cmc_callbacks * callbacks) \ @@ -472,23 +450,29 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + K max_key; \ + V max_val; \ + size_t first = 0; \ \ - K max_key = CMC_(PFX, _iter_key)(&iter); \ - V max_val = CMC_(PFX, _iter_value)(&iter); \ - \ - CMC_(PFX, _iter_next)(&iter); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (; first < _map_->capacity; first++) \ { \ - K iter_key = CMC_(PFX, _iter_key)(&iter); \ - V iter_val = CMC_(PFX, _iter_value)(&iter); \ - \ - if (_map_->f_key->cmp(iter_key, max_key) > 0) \ + if (_map_->buffer[first].state == CMC_ES_FILLED) \ { \ - max_key = iter_key; \ - max_val = iter_val; \ + max_key = _map_->buffer[first].key; \ + max_val = _map_->buffer[first].value; \ + break; \ + } \ + } \ + \ + for (size_t i = first + 1; i < _map_->capacity; i++) \ + { \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ + { \ + max_key = _map_->buffer[first].key; \ + max_val = _map_->buffer[first].value; \ + } \ } \ } \ \ @@ -511,23 +495,29 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + K min_key; \ + V min_val; \ + size_t first = 0; \ \ - K min_key = CMC_(PFX, _iter_key)(&iter); \ - V min_val = CMC_(PFX, _iter_value)(&iter); \ - \ - CMC_(PFX, _iter_next)(&iter); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (; first < _map_->capacity; first++) \ { \ - K iter_key = CMC_(PFX, _iter_key)(&iter); \ - V iter_val = CMC_(PFX, _iter_value)(&iter); \ - \ - if (_map_->f_key->cmp(iter_key, min_key) < 0) \ + if (_map_->buffer[first].state == CMC_ES_FILLED) \ { \ - min_key = iter_key; \ - min_val = iter_val; \ + min_key = _map_->buffer[first].key; \ + min_val = _map_->buffer[first].value; \ + break; \ + } \ + } \ + \ + for (size_t i = first + 1; i < _map_->capacity; i++) \ + { \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) > 0) \ + { \ + min_key = _map_->buffer[first].key; \ + min_val = _map_->buffer[first].value; \ + } \ } \ } \ \ @@ -672,15 +662,16 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ - \ - /* TODO turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - V value = CMC_(PFX, _iter_value)(&iter); \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + K key = _map_->buffer[i].key; \ + V value = _map_->buffer[i].value; \ \ - CMC_(PFX, _insert)(_new_map_, key, value); \ + /* TODO check this for possible errors */ \ + CMC_(PFX, _insert)(_new_map_, key, value); \ + } \ } \ \ /* Unlikely */ \ @@ -776,20 +767,28 @@ if (_map1_->count != _map2_->count) \ return false; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ + /* Optimize loop using the smallest hashtable */ \ + struct SNAME *_map_a_; \ + struct SNAME *_map_b_; \ \ - /* TODO optimize this loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \ + _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \ + \ + for (size_t i = 0; i < _map_a_->capacity; i++) \ { \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)( \ - _map2_, CMC_(PFX, _iter_key)(&iter)); \ + if (_map_a_->buffer[i].state == CMC_ES_FILLED) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_map_a_->buffer[i]); \ \ - if (entry == NULL) \ - return false; \ + struct CMC_DEF_ENTRY(SNAME) *entry_b = \ + CMC_(PFX, _impl_get_entry)(_map_b_, entry_a->key); \ \ - if (_map1_->f_val->cmp(entry->value, \ - CMC_(PFX, _iter_value)(&iter)) != 0) \ - return false; \ + if (!entry_b) \ + return false; \ + \ + if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) \ + return false; \ + } \ } \ \ return true; \ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 188a90c..b3e5e71 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -36,52 +36,68 @@ CMC_EXT_CMC_DEQUE_INIT_SOURCE_( \ CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ - \ - struct SNAME CMC_(PFX, _init)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME CMC_(PFX, _init_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); +#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ + \ + struct SNAME CMC_(PFX, _init)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME CMC_(PFX, _init_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _release)(struct SNAME _deque_); -#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ - \ - struct SNAME CMC_(PFX, _init)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \ - } \ - \ - struct SNAME CMC_(PFX, _init_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - struct SNAME _deque_ = { 0 }; \ - \ - if (capacity < 1) \ - return _deque_; \ - \ - if (!f_val) \ - return _deque_; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_deque_.buffer) \ - return _deque_; \ - \ - _deque_.capacity = capacity; \ - _deque_.count = 0; \ - _deque_.front = 0; \ - _deque_.back = 0; \ - _deque_.flag = CMC_FLAG_OK; \ - _deque_.f_val = f_val; \ - _deque_.alloc = alloc; \ - _deque_.callbacks = callbacks; \ - \ - return _deque_; \ +#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ + \ + struct SNAME CMC_(PFX, _init)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \ + } \ + \ + struct SNAME CMC_(PFX, _init_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ + { \ + struct SNAME _deque_ = { 0 }; \ + \ + if (capacity < 1) \ + return _deque_; \ + \ + if (!f_val) \ + return _deque_; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ + \ + if (!_deque_.buffer) \ + return _deque_; \ + \ + _deque_.capacity = capacity; \ + _deque_.count = 0; \ + _deque_.front = 0; \ + _deque_.back = 0; \ + _deque_.flag = CMC_FLAG_OK; \ + _deque_.f_val = f_val; \ + _deque_.alloc = alloc; \ + _deque_.callbacks = callbacks; \ + \ + return _deque_; \ + } \ + \ + void CMC_(PFX, _release)(struct SNAME _deque_) \ + { \ + if (_deque_.f_val->free) \ + { \ + for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ + { \ + _deque_.f_val->free(_deque_.buffer[i]); \ + \ + i = (i + 1) % _deque_.capacity; \ + } \ + } \ + \ + _deque_.alloc->free(_deque_.buffer); \ } /** diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 10ba62b..44fea59 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -46,7 +46,8 @@ 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 cmc_callbacks * callbacks); \ + void CMC_(PFX, _release)(struct SNAME _map_); #define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, K, V) \ \ @@ -97,6 +98,27 @@ _map_.callbacks = callbacks; \ \ return _map_; \ + } \ + \ + void CMC_(PFX, _release)(struct SNAME _map_) \ + { \ + if (_map_.f_key->free || _map_.f_val->free) \ + { \ + 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->free) \ + _map_.f_key->free(entry->key); \ + if (_map_.f_val->free) \ + _map_.f_val->free(entry->value); \ + } \ + } \ + } \ + \ + _map_.alloc->free(_map_.buffer); \ } /** From 770ec1c4c731ce21a58bcdb6e2600b62e8688fd2 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 4 Jun 2020 00:33:13 -0300 Subject: [PATCH 21/51] More migrations to EXT --- src/cmc/list.h | 624 ++++++--------------------------------- src/ext/cmc/linkedlist.h | 2 +- src/ext/cmc/list.h | 527 +++++++++++++++++++++++++++++++++ src/macro_collections.h | 1 + tests/to_string.c | 12 + 5 files changed, 631 insertions(+), 535 deletions(-) create mode 100644 src/ext/cmc/list.h diff --git a/src/cmc/list.h b/src/cmc/list.h index d0254cd..1353481 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -48,20 +48,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * List specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core List implementation */ @@ -80,146 +66,94 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target list */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ - /* Collection Sequence Input and Output */ \ - bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ - size_t size); \ - bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ - size_t size, size_t index); \ - bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ - size_t size); \ - bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, \ - size_t to); \ - struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ - size_t to); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ - V CMC_(PFX, _back)(struct SNAME * _list_); \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ - bool from_start); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - bool CMC_(PFX, _full)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); +#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \ + \ + /* List Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ + \ + /* Current array capacity */ \ + size_t capacity; \ + \ + /* Current amount of elements */ \ + size_t count; \ + \ + /* Flags indicating errors or success */ \ + int flag; \ + \ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ + \ + /* Custom allocation functions */ \ + struct cmc_alloc_node *alloc; \ + \ + /* Custom callback functions */ \ + struct cmc_callbacks *callbacks; \ + }; \ + \ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ + \ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ + \ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ + \ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ + \ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ + \ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ + \ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct cmc_alloc_node * alloc, \ + struct cmc_callbacks * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ + V CMC_(PFX, _back)(struct SNAME * _list_); \ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ + bool from_start); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + bool CMC_(PFX, _full)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); /* ------------------------------------------------------------------------- * Source @@ -465,177 +399,6 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " return true; \ } \ \ - bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ - size_t size) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + size, _list_->buffer, \ - _list_->count * sizeof(V)); \ - \ - memcpy(_list_->buffer, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ - size_t size, size_t index) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - return CMC_(PFX, _seq_push_front)(_list_, values, size); \ - else if (index == _list_->count) \ - return CMC_(PFX, _seq_push_back)(_list_, values, size); \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + index + size, _list_->buffer + index, \ - (_list_->count - index) * sizeof(V)); \ - \ - memcpy(_list_->buffer + index, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ - size_t size) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \ - { \ - if (from > to) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (to >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - size_t length = (to - from + 1); \ - \ - memmove(_list_->buffer + from, _list_->buffer + to + 1, \ - (_list_->count - to - 1) * sizeof(V)); \ - \ - memset(_list_->buffer + _list_->count - length, 0, \ - length * sizeof(V)); \ - \ - _list_->count -= to - from + 1; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ - size_t to) \ - { \ - if (from > to) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return NULL; \ - } \ - \ - if (to >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - size_t length = to - from + 1; \ - \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - length, _list_->f_val, _list_->alloc, _list_->callbacks); \ - \ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \ - \ - memmove(_list_->buffer + from, _list_->buffer + to + 1, \ - (_list_->count - to - 1) * sizeof(V)); \ - \ - memset(_list_->buffer + _list_->count - length, 0, \ - length * sizeof(V)); \ - \ - _list_->count -= length; \ - result->count = length; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return result; \ - } \ - \ V CMC_(PFX, _front)(struct SNAME * _list_) \ { \ if (CMC_(PFX, _empty)(_list_)) \ @@ -869,219 +632,12 @@ static const char *cmc_cmc_string_fmt_list = "struct %s<%s> " \ for (size_t i = 0; i < _list1_->count; i++) \ { \ - if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \ - 0) \ + if (0 != \ + _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) \ return false; \ } \ \ return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ - { \ - struct cmc_string str; \ - struct SNAME *l_ = _list_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_list, \ - #SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \ - l_->flag, l_->f_val, l_->alloc, l_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->target->count - 1; \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ } #endif /* CMC_CMC_LIST_H */ diff --git a/src/ext/cmc/linkedlist.h b/src/ext/cmc/linkedlist.h index 15d1f3a..bb1f18e 100644 --- a/src/ext/cmc/linkedlist.h +++ b/src/ext/cmc/linkedlist.h @@ -1,7 +1,7 @@ /** * ext/cmc/linkedlist.h * - * Creation Date: 26/05/2020 + * Creation Date: 03/06/2020 * * Authors: * Leonardo Vencovsky (https://github.com/LeoVen) diff --git a/src/ext/cmc/list.h b/src/ext/cmc/list.h new file mode 100644 index 0000000..155d6d7 --- /dev/null +++ b/src/ext/cmc/list.h @@ -0,0 +1,527 @@ +/** + * ext/cmc/list.h + * + * Creation Date: 04/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_LIST_H +#define CMC_EXT_CMC_LIST_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC List. + */ +#define CMC_EXT_CMC_LIST_PARTS ITER, SEQ, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_LIST_ITER(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_HEADER_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_SOURCE_( \ + CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_ITER_HEADER_(PFX, SNAME, V) \ + \ + /* List Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target List */ \ + struct SNAME *target; \ + \ + /* Cursor's position (index) */ \ + size_t cursor; \ + \ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ + \ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ + \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_LIST_ITER_SOURCE_(PFX, SNAME, V) \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ + \ + return iter; \ + } \ + \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ + \ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ + \ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ + \ + return iter; \ + } \ + \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ + \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ + \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->target->count - 1; \ + iter->end = true; \ + \ + return true; \ + } \ + \ + return false; \ + } \ + \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor++; \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor--; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->end) \ + return false; \ + \ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ + \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor += steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t steps) \ + { \ + if (iter->start) \ + return false; \ + \ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ + \ + if (steps == 0 || iter->cursor < steps) \ + return false; \ + \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + \ + iter->cursor -= steps; \ + \ + return true; \ + } \ + \ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ + size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ + \ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ + \ + return true; \ + } \ + \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ + \ + return iter->target->buffer[iter->cursor]; \ + } \ + \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ + \ + return &(iter->target->buffer[iter->cursor]); \ + } \ + \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ + } + +/** + * SEQ + */ +#define CMC_EXT_CMC_LIST_SEQ(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_SEQ_HEADER_(PFX, SNAME, V) \ + \ + /* List Sequence Input and Output */ \ + bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ + size_t size); \ + bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ + size_t size, size_t index); \ + bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ + size_t size); \ + bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, \ + size_t to); \ + struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ + size_t to); + +#define CMC_EXT_CMC_LIST_SEQ_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ + size_t size) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ + \ + memmove(_list_->buffer + size, _list_->buffer, \ + _list_->count * sizeof(V)); \ + \ + memcpy(_list_->buffer, values, size * sizeof(V)); \ + \ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ + size_t size, size_t index) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + if (index > _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ + \ + if (index == 0) \ + return CMC_(PFX, _seq_push_front)(_list_, values, size); \ + else if (index == _list_->count) \ + return CMC_(PFX, _seq_push_back)(_list_, values, size); \ + \ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ + \ + memmove(_list_->buffer + index + size, _list_->buffer + index, \ + (_list_->count - index) * sizeof(V)); \ + \ + memcpy(_list_->buffer + index, values, size * sizeof(V)); \ + \ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ + size_t size) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ + \ + memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \ + \ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ + \ + return true; \ + } \ + \ + bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \ + { \ + if (from > to) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ + \ + if (to >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ + \ + size_t length = (to - from + 1); \ + \ + memmove(_list_->buffer + from, _list_->buffer + to + 1, \ + (_list_->count - to - 1) * sizeof(V)); \ + \ + memset(_list_->buffer + _list_->count - length, 0, \ + length * sizeof(V)); \ + \ + _list_->count -= to - from + 1; \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return true; \ + } \ + \ + struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ + size_t to) \ + { \ + if (from > to) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return NULL; \ + } \ + \ + if (to >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ + \ + size_t length = to - from + 1; \ + \ + struct SNAME *result = CMC_(PFX, _new_custom)( \ + length, _list_->f_val, _list_->alloc, _list_->callbacks); \ + \ + if (!result) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ + \ + memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \ + \ + memmove(_list_->buffer + from, _list_->buffer + to + 1, \ + (_list_->count - to - 1) * sizeof(V)); \ + \ + memset(_list_->buffer + _list_->count - length, 0, \ + length * sizeof(V)); \ + \ + _list_->count -= length; \ + result->count = length; \ + \ + _list_->flag = CMC_FLAG_OK; \ + \ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ + \ + return result; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_LIST_STR(PARAMS) \ + CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \ + CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_STR_HEADER_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_LIST_STR_SOURCE_(PFX, SNAME, V) \ + \ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ + { \ + struct SNAME *l_ = _list_; \ + \ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, \ + l_->buffer, l_->capacity, l_->count, l_->flag, \ + l_->f_val, l_->alloc, l_->callbacks); \ + } \ + \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ + const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ + \ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ + return false; \ + \ + if (i + 1 < _list_->count) \ + fprintf(fptr, "%s", separator); \ + } \ + \ + fprintf(fptr, "%s", end); \ + \ + return true; \ + } + +#endif /* CMC_EXT_CMC_LIST_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 6ad0562..50bb4a2 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -61,6 +61,7 @@ #include "ext/cmc/heap.h" /* Added in 01/06/2020 */ #include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */ #include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */ +#include "ext/cmc/list.h" /* Added in 04/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/to_string.c b/tests/to_string.c index 1aad044..72dd3fd 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -11,6 +11,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h, heap, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih, intervalheap, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int)) struct { @@ -37,6 +38,7 @@ int main(void) struct heap *h = h_new(100, CMC_MAX_HEAP, (struct heap_fval *)&int_ftab); struct intervalheap *ih = ih_new(100, (struct intervalheap_fval *)&int_ftab); struct linkedlist *ll = ll_new((struct linkedlist_fval *)&int_ftab); + struct list *l = l_new(100, (struct list_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -54,6 +56,8 @@ int main(void) ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); ll_to_string(ll, stdout); ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); + l_to_string(l, stdout); + l_print(l, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -65,6 +69,7 @@ int main(void) h_insert(h, 0); ih_insert(ih, 0); ll_push_back(ll, 0); + l_push_back(l, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -82,6 +87,8 @@ int main(void) ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); ll_to_string(ll, stdout); ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); + l_to_string(l, stdout); + l_print(l, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -93,6 +100,7 @@ int main(void) h_insert(h, i); ih_insert(ih, i); ll_push_back(ll, i); + l_push_back(l, i); } fprintf(stdout, "\n"); @@ -113,6 +121,8 @@ int main(void) ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); ll_to_string(ll, stdout); ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); + l_to_string(l, stdout); + l_print(l, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm); @@ -121,6 +131,8 @@ int main(void) hs_free(hs); h_free(h); ih_free(ih); + ll_free(ll); + l_free(l); } // clang-format on From aa033b03160443ffe1f9fd55e1a96c7a65adfeb7 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 4 Jun 2020 17:20:47 -0300 Subject: [PATCH 22/51] Massive changes, unit tests halted Code format changes that significantly reduce file sizes Working towards many new features at the same time Callbacks are going to be optional Everything is still breaking --- .clang-format | 4 +- src/cmc/bitset.h | 1007 ++++---- src/cmc/deque.h | 904 ++++--- src/cmc/hashbidimap.h | 2735 ++++++++++---------- src/cmc/hashmap.h | 1536 ++++++------ src/cmc/hashmultimap.h | 2002 +++++++-------- src/cmc/hashmultiset.h | 1660 ++++++------ src/cmc/hashset.h | 1219 +++++---- src/cmc/heap.h | 892 ++++--- src/cmc/intervalheap.h | 1709 ++++++------- src/cmc/linkedlist.h | 1131 ++++----- src/cmc/list.h | 1103 ++++---- src/cmc/queue.h | 1374 +++++----- src/cmc/sortedlist.h | 1620 ++++++------ src/cmc/stack.h | 1202 +++++---- src/cmc/treemap.h | 2421 +++++++++--------- src/cmc/treeset.h | 2581 ++++++++++--------- src/cor/alloc.h | 8 +- src/cor/callbacks.h | 32 +- src/cor/flags.h | 6 +- src/ext/cmc/deque.h | 727 +++--- src/ext/cmc/hashmap.h | 943 ++++--- src/ext/cmc/hashmultimap.h | 832 +++--- src/ext/cmc/hashmultiset.h | 1309 +++++----- src/ext/cmc/hashset.h | 1235 +++++---- src/ext/cmc/heap.h | 529 ++-- src/ext/cmc/intervalheap.h | 523 ++-- src/ext/cmc/linkedlist.h | 1046 ++++---- src/ext/cmc/list.h | 899 ++++--- src/macro_collections.h | 63 +- src/utl/assert.h | 4449 ++++++++++++++++----------------- src/utl/foreach.h | 10 +- src/utl/log.h | 37 +- src/utl/test.h | 255 +- src/utl/thread.h | 3 +- src/utl/timer.h | 21 +- tests/main/main.c | 30 +- tests/main/src/bitset.c | 31 +- tests/main/src/deque.c | 36 +- tests/main/src/hashbidimap.c | 146 +- tests/main/src/hashmap.c | 61 +- tests/main/src/hashmultimap.c | 89 +- tests/main/src/hashmultiset.c | 155 +- tests/main/src/hashset.c | 60 +- tests/main/src/heap.c | 35 +- tests/main/src/intervalheap.c | 41 +- tests/main/src/linkedlist.c | 30 +- tests/main/src/list.c | 71 +- tests/main/src/queue.c | 48 +- tests/main/src/sortedlist.c | 70 +- tests/main/src/stack.c | 41 +- tests/main/src/treemap.c | 80 +- tests/main/src/treeset.c | 91 +- tests/main/unt/bitset.c | 51 +- tests/main/unt/deque.c | 64 +- tests/main/unt/foreach.c | 219 +- tests/main/unt/hashbidimap.c | 109 +- tests/main/unt/hashmap.c | 84 +- tests/main/unt/hashmultimap.c | 109 +- tests/main/unt/hashmultiset.c | 58 +- tests/main/unt/hashset.c | 53 +- tests/main/unt/heap.c | 18 +- tests/main/unt/intervalheap.c | 39 +- tests/main/unt/linkedlist.c | 16 +- tests/main/unt/list.c | 15 +- tests/main/unt/queue.c | 27 +- tests/main/unt/sortedlist.c | 19 +- tests/main/unt/stack.c | 15 +- tests/main/unt/treemap.c | 24 +- tests/main/unt/treeset.c | 15 +- tests/main/unt/utl.c | 20 +- 71 files changed, 19023 insertions(+), 21074 deletions(-) diff --git a/.clang-format b/.clang-format index 36f4664..3c0bd05 100644 --- a/.clang-format +++ b/.clang-format @@ -1,13 +1,13 @@ # clang-format 9.0.0 Language: Cpp BasedOnStyle: LLVM -AlignEscapedNewlines: Left +AlignEscapedNewlines: DontAlign AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false BreakBeforeBraces: Allman BreakStringLiterals: false -ColumnLimit: 80 +ColumnLimit: 120 Cpp11BracedListStyle: false ForEachMacros: ["CMC_FOREACH", "CMC_FOREACH_REV"] IndentCaseLabels: true diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index f55bf96..9fa4237 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -56,543 +56,508 @@ static const char *cmc_cmc_string_fmt_bitset = "struct %s " /** * Core BitSet implementation */ -#define CMC_CMC_BITSET_CORE(PARAMS) \ +#define CMC_CMC_BITSET_CORE(PARAMS) \ CMC_CMC_BITSET_CORE_HEADER(PARAMS) \ CMC_CMC_BITSET_CORE_SOURCE(PARAMS) -#define CMC_CMC_BITSET_CORE_HEADER(PARAMS) \ - CMC_CMC_BITSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) +#define CMC_CMC_BITSET_CORE_HEADER(PARAMS) CMC_CMC_BITSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) -#define CMC_CMC_BITSET_CORE_SOURCE(PARAMS) \ - CMC_CMC_BITSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) +#define CMC_CMC_BITSET_CORE_SOURCE(PARAMS) CMC_CMC_BITSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_BITSET_CORE_HEADER_(PFX, SNAME) \ - \ - /* BitSet Structure */ \ - struct SNAME \ - { \ - /* Dynamic Array of Bits */ \ - cmc_bitset_word *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* BitSet Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target bitset */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - cmc_bitset_word cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t n_bits); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - struct SNAME CMC_(PFX, _init)(size_t n_bits); \ - struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _free)(struct SNAME * _bitset_); \ - void CMC_(PFX, _release)(struct SNAME _bitset_); \ - void CMC_(PFX, _customize)(struct SNAME * _bitset_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _set)(struct SNAME * _bitset_, size_t bit_index); \ - bool CMC_(PFX, _set_range)(struct SNAME * _bitset_, size_t from, \ - size_t to); \ - bool CMC_(PFX, _clear)(struct SNAME * _bitset_, size_t bit_index); \ - bool CMC_(PFX, _clear_range)(struct SNAME * _bitset_, size_t from, \ - size_t to); \ - bool CMC_(PFX, _flip)(struct SNAME * _bitset_, size_t bit_index); \ - bool CMC_(PFX, _flip_range)(struct SNAME * _bitset_, size_t from, \ - size_t to); \ - bool CMC_(PFX, _put)(struct SNAME * _bitset_, size_t bit_index, \ - bool state); \ - bool CMC_(PFX, _put_range)(struct SNAME * _bitset_, size_t from, \ - size_t to, bool state); \ - bool CMC_(PFX, _set_all)(struct SNAME * _bitset_); \ - bool CMC_(PFX, _clear_all)(struct SNAME * _bitset_); \ - bool CMC_(PFX, _flip_all)(struct SNAME * _bitset_); \ - /* Element Access */ \ - bool CMC_(PFX, _get)(struct SNAME * _bitset_, size_t bit_index); \ - /* Collection State */ \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _bitset_, size_t n_bits); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - /* Iterator State */ \ - /* Iterator Movement */ \ - /* Iterator Access */ \ - \ - /* Utility Methods */ \ - /* Translates a bit index to a word index */ \ - static inline size_t CMC_(PFX, _bit_to_index)(size_t idx) \ - { \ +#define CMC_CMC_BITSET_CORE_HEADER_(PFX, SNAME) \ +\ + /* BitSet Structure */ \ + struct SNAME \ + { \ + /* Dynamic Array of Bits */ \ + cmc_bitset_word *buffer; \ +\ + /* Current array capacity */ \ + size_t capacity; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* BitSet Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target bitset */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + cmc_bitset_word cursor; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t n_bits); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + struct SNAME CMC_(PFX, _init)(size_t n_bits); \ + struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _free)(struct SNAME * _bitset_); \ + void CMC_(PFX, _release)(struct SNAME _bitset_); \ + void CMC_(PFX, _customize)(struct SNAME * _bitset_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _set)(struct SNAME * _bitset_, size_t bit_index); \ + bool CMC_(PFX, _set_range)(struct SNAME * _bitset_, size_t from, size_t to); \ + bool CMC_(PFX, _clear)(struct SNAME * _bitset_, size_t bit_index); \ + bool CMC_(PFX, _clear_range)(struct SNAME * _bitset_, size_t from, size_t to); \ + bool CMC_(PFX, _flip)(struct SNAME * _bitset_, size_t bit_index); \ + bool CMC_(PFX, _flip_range)(struct SNAME * _bitset_, size_t from, size_t to); \ + bool CMC_(PFX, _put)(struct SNAME * _bitset_, size_t bit_index, bool state); \ + bool CMC_(PFX, _put_range)(struct SNAME * _bitset_, size_t from, size_t to, bool state); \ + bool CMC_(PFX, _set_all)(struct SNAME * _bitset_); \ + bool CMC_(PFX, _clear_all)(struct SNAME * _bitset_); \ + bool CMC_(PFX, _flip_all)(struct SNAME * _bitset_); \ + /* Element Access */ \ + bool CMC_(PFX, _get)(struct SNAME * _bitset_, size_t bit_index); \ + /* Collection State */ \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _bitset_, size_t n_bits); \ +\ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + /* Iterator State */ \ + /* Iterator Movement */ \ + /* Iterator Access */ \ +\ + /* Utility Methods */ \ + /* Translates a bit index to a word index */ \ + static inline size_t CMC_(PFX, _bit_to_index)(size_t idx) \ + { \ /* Calculate how many shifts based on the size of cmc_bitset_word */ \ - static const size_t shift = \ - ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \ - ? 6 \ - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 \ - ? 5 \ - : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; \ - \ - return idx >> shift; \ + static const size_t shift = \ + ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \ + ? 6 \ + : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; \ +\ + return idx >> shift; \ } /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_BITSET_CORE_SOURCE_(PFX, SNAME) \ - \ - /* Implementation Detail Functions */ \ - bool CMC_(PFX, _impl_resize)(struct SNAME * _bitset_, size_t n_bits, \ - bool do_resize); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t n_bits) \ - { \ - return CMC_(PFX, _new_custom)(n_bits, NULL, NULL); \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (n_bits < 1) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ - \ - struct SNAME *_bitset_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_bitset_) \ - return NULL; \ - \ - _bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ - \ - if (!_bitset_->buffer) \ - { \ - alloc->free(_bitset_); \ - return NULL; \ - } \ - \ - _bitset_->capacity = capacity; \ - _bitset_->flag = CMC_FLAG_OK; \ - _bitset_->alloc = alloc; \ - _bitset_->callbacks = callbacks; \ - \ - return _bitset_; \ - } \ - \ - struct SNAME CMC_(PFX, _init)(size_t n_bits) \ - { \ - return CMC_(PFX, _init_custom)(n_bits, NULL, NULL); \ - } \ - \ - struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - struct SNAME _bitset_ = { 0 }; \ - \ - if (n_bits < 1) \ - return _bitset_; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ - \ - _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ - \ - if (!_bitset_.buffer) \ - return _bitset_; \ - \ - _bitset_.capacity = capacity; \ - _bitset_.flag = CMC_FLAG_OK; \ - _bitset_.alloc = alloc; \ - _bitset_.callbacks = callbacks; \ - \ - return _bitset_; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _bitset_) \ - { \ - free(_bitset_->buffer); \ - free(_bitset_); \ - } \ - \ - void CMC_(PFX, _release)(struct SNAME _bitset_) \ - { \ - free(_bitset_.buffer); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _bitset_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _bitset_->alloc = &cmc_alloc_node_default; \ - else \ - _bitset_->alloc = alloc; \ - \ - _bitset_->callbacks = callbacks; \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _set)(struct SNAME * _bitset_, size_t bit_index) \ - { \ - if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ - return false; \ - \ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ - \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ - \ - _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->create) \ - _bitset_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _set_range)(struct SNAME * _bitset_, size_t from, \ - size_t to) \ - { \ - if (to < from) \ - { \ - _bitset_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ - return false; \ - \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ - \ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ - \ - /* 1111 ... 1111 */ \ - const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ - \ - cmc_bitset_word shift_start = from % bits; \ - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ - \ - cmc_bitset_word start_mask = ones << shift_start; \ - cmc_bitset_word end_mask = ones >> shift_end; \ - \ - if (start_index == end_index) \ - { \ - _bitset_->buffer[end_index] |= (start_mask & end_mask); \ - } \ - else \ - { \ - _bitset_->buffer[start_index] |= start_mask; \ - \ - for (size_t i = start_index + 1; i < end_index; i++) \ - _bitset_->buffer[i] |= ~((cmc_bitset_word)0); \ - \ - _bitset_->buffer[end_index] |= end_mask; \ - } \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->create) \ - _bitset_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _clear)(struct SNAME * _bitset_, size_t bit_index) \ - { \ - if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ - return false; \ - \ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ - \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ - \ - _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->delete) \ - _bitset_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _clear_range)(struct SNAME * _bitset_, size_t from, \ - size_t to) \ - { \ - if (to < from) \ - { \ - _bitset_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ - return false; \ - \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ - \ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ - \ - /* 1111 ... 1111 */ \ - const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ - \ - cmc_bitset_word shift_start = from % bits; \ - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ - \ - cmc_bitset_word start_mask = ones << shift_start; \ - cmc_bitset_word end_mask = ones >> shift_end; \ - \ - if (start_index == end_index) \ - { \ - _bitset_->buffer[end_index] &= ~(start_mask & end_mask); \ - } \ - else \ - { \ - _bitset_->buffer[start_index] &= ~start_mask; \ - \ - for (size_t i = start_index + 1; i < end_index; i++) \ - _bitset_->buffer[i] = 0; \ - \ - _bitset_->buffer[end_index] &= ~end_mask; \ - } \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->delete) \ - _bitset_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _flip)(struct SNAME * _bitset_, size_t bit_index) \ - { \ - if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ - return false; \ - \ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ - \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ - \ - _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->update) \ - _bitset_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _flip_range)(struct SNAME * _bitset_, size_t from, \ - size_t to) \ - { \ - if (to < from) \ - { \ - _bitset_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ - return false; \ - \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ - \ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ - \ - /* 1111 ... 1111 */ \ - const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ - \ - cmc_bitset_word shift_start = from % bits; \ - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ - \ - cmc_bitset_word start_mask = ones << shift_start; \ - cmc_bitset_word end_mask = ones >> shift_end; \ - \ - if (start_index == end_index) \ - { \ - _bitset_->buffer[end_index] ^= (start_mask & end_mask); \ - } \ - else \ - { \ - _bitset_->buffer[start_index] ^= start_mask; \ - \ - for (size_t i = start_index + 1; i < end_index; i++) \ - _bitset_->buffer[i] ^= ones; \ - \ - _bitset_->buffer[end_index] ^= end_mask; \ - } \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->update) \ - _bitset_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _put)(struct SNAME * _bitset_, size_t bit_index, \ - bool state) \ - { \ - if (state) \ - return CMC_(PFX, _set)(_bitset_, bit_index); \ - else \ - return CMC_(PFX, _clear)(_bitset_, bit_index); \ - } \ - \ - bool CMC_(PFX, _put_range)(struct SNAME * _bitset_, size_t from, \ - size_t to, bool state) \ - { \ - if (state) \ - return CMC_(PFX, _set_range)(_bitset_, from, to); \ - else \ - return CMC_(PFX, _clear_range)(_bitset_, from, to); \ - } \ - \ - bool CMC_(PFX, _set_all)(struct SNAME * _bitset_) \ - { \ - for (size_t i = 0; i < _bitset_->capacity; i++) \ - _bitset_->buffer[i] = ~((cmc_bitset_word)0); \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->create) \ - _bitset_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _clear_all)(struct SNAME * _bitset_) \ - { \ - for (size_t i = 0; i < _bitset_->capacity; i++) \ - _bitset_->buffer[i] = 0; \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->delete) \ - _bitset_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _flip_all)(struct SNAME * _bitset_) \ - { \ - for (size_t i = 0; i < _bitset_->capacity; i++) \ - _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->create) \ - _bitset_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _get)(struct SNAME * _bitset_, size_t bit_index) \ - { \ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ - \ - cmc_bitset_word w = \ - _bitset_->buffer[CMC_(PFX, _bit_to_index)(bit_index)]; \ - \ - return w & ((cmc_bitset_word)1 << (bit_index % bits)); \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _bitset_, size_t n_bits) \ - { \ - return CMC_(PFX, _impl_resize)(_bitset_, n_bits, true); \ - } \ - \ +#define CMC_CMC_BITSET_CORE_SOURCE_(PFX, SNAME) \ +\ + /* Implementation Detail Functions */ \ + bool CMC_(PFX, _impl_resize)(struct SNAME * _bitset_, size_t n_bits, bool do_resize); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t n_bits) \ + { \ + return CMC_(PFX, _new_custom)(n_bits, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (n_bits < 1) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ +\ + struct SNAME *_bitset_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_bitset_) \ + return NULL; \ +\ + _bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ +\ + if (!_bitset_->buffer) \ + { \ + alloc->free(_bitset_); \ + return NULL; \ + } \ +\ + _bitset_->capacity = capacity; \ + _bitset_->flag = CMC_FLAG_OK; \ + _bitset_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_bitset_, callbacks); \ +\ + return _bitset_; \ + } \ +\ + struct SNAME CMC_(PFX, _init)(size_t n_bits) \ + { \ + return CMC_(PFX, _init_custom)(n_bits, NULL, NULL); \ + } \ +\ + struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + struct SNAME _bitset_ = { 0 }; \ +\ + if (n_bits < 1) \ + return _bitset_; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ +\ + _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ +\ + if (!_bitset_.buffer) \ + return _bitset_; \ +\ + _bitset_.capacity = capacity; \ + _bitset_.flag = CMC_FLAG_OK; \ + _bitset_.alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(&_bitset_, callbacks); \ +\ + return _bitset_; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _bitset_) \ + { \ + free(_bitset_->buffer); \ + free(_bitset_); \ + } \ +\ + void CMC_(PFX, _release)(struct SNAME _bitset_) \ + { \ + free(_bitset_.buffer); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _bitset_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _bitset_->alloc = &cmc_alloc_node_default; \ + else \ + _bitset_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_bitset_, callbacks); \ +\ + _bitset_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _set)(struct SNAME * _bitset_, size_t bit_index) \ + { \ + if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ + return false; \ +\ + /* How many bits in a word */ \ + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ +\ + size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ +\ + _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, create); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _set_range)(struct SNAME * _bitset_, size_t from, size_t to) \ + { \ + if (to < from) \ + { \ + _bitset_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ + return false; \ +\ + size_t start_index = CMC_(PFX, _bit_to_index)(from); \ + size_t end_index = CMC_(PFX, _bit_to_index)(to); \ +\ + /* How many bits in a word */ \ + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ +\ + /* 1111 ... 1111 */ \ + const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ +\ + cmc_bitset_word shift_start = from % bits; \ + cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ +\ + cmc_bitset_word start_mask = ones << shift_start; \ + cmc_bitset_word end_mask = ones >> shift_end; \ +\ + if (start_index == end_index) \ + { \ + _bitset_->buffer[end_index] |= (start_mask & end_mask); \ + } \ + else \ + { \ + _bitset_->buffer[start_index] |= start_mask; \ +\ + for (size_t i = start_index + 1; i < end_index; i++) \ + _bitset_->buffer[i] |= ~((cmc_bitset_word)0); \ +\ + _bitset_->buffer[end_index] |= end_mask; \ + } \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, create); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _clear)(struct SNAME * _bitset_, size_t bit_index) \ + { \ + if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ + return false; \ +\ + /* How many bits in a word */ \ + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ +\ + size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ +\ + _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, delete); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _clear_range)(struct SNAME * _bitset_, size_t from, size_t to) \ + { \ + if (to < from) \ + { \ + _bitset_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ + return false; \ +\ + size_t start_index = CMC_(PFX, _bit_to_index)(from); \ + size_t end_index = CMC_(PFX, _bit_to_index)(to); \ +\ + /* How many bits in a word */ \ + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ +\ + /* 1111 ... 1111 */ \ + const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ +\ + cmc_bitset_word shift_start = from % bits; \ + cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ +\ + cmc_bitset_word start_mask = ones << shift_start; \ + cmc_bitset_word end_mask = ones >> shift_end; \ +\ + if (start_index == end_index) \ + { \ + _bitset_->buffer[end_index] &= ~(start_mask & end_mask); \ + } \ + else \ + { \ + _bitset_->buffer[start_index] &= ~start_mask; \ +\ + for (size_t i = start_index + 1; i < end_index; i++) \ + _bitset_->buffer[i] = 0; \ +\ + _bitset_->buffer[end_index] &= ~end_mask; \ + } \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, delete); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _flip)(struct SNAME * _bitset_, size_t bit_index) \ + { \ + if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ + return false; \ +\ + /* How many bits in a word */ \ + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ +\ + size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ +\ + _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, update); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _flip_range)(struct SNAME * _bitset_, size_t from, size_t to) \ + { \ + if (to < from) \ + { \ + _bitset_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ + return false; \ +\ + size_t start_index = CMC_(PFX, _bit_to_index)(from); \ + size_t end_index = CMC_(PFX, _bit_to_index)(to); \ +\ + /* How many bits in a word */ \ + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ +\ + /* 1111 ... 1111 */ \ + const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ +\ + cmc_bitset_word shift_start = from % bits; \ + cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ +\ + cmc_bitset_word start_mask = ones << shift_start; \ + cmc_bitset_word end_mask = ones >> shift_end; \ +\ + if (start_index == end_index) \ + { \ + _bitset_->buffer[end_index] ^= (start_mask & end_mask); \ + } \ + else \ + { \ + _bitset_->buffer[start_index] ^= start_mask; \ +\ + for (size_t i = start_index + 1; i < end_index; i++) \ + _bitset_->buffer[i] ^= ones; \ +\ + _bitset_->buffer[end_index] ^= end_mask; \ + } \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, update); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _put)(struct SNAME * _bitset_, size_t bit_index, bool state) \ + { \ + if (state) \ + return CMC_(PFX, _set)(_bitset_, bit_index); \ + else \ + return CMC_(PFX, _clear)(_bitset_, bit_index); \ + } \ +\ + bool CMC_(PFX, _put_range)(struct SNAME * _bitset_, size_t from, size_t to, bool state) \ + { \ + if (state) \ + return CMC_(PFX, _set_range)(_bitset_, from, to); \ + else \ + return CMC_(PFX, _clear_range)(_bitset_, from, to); \ + } \ +\ + bool CMC_(PFX, _set_all)(struct SNAME * _bitset_) \ + { \ + for (size_t i = 0; i < _bitset_->capacity; i++) \ + _bitset_->buffer[i] = ~((cmc_bitset_word)0); \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, create); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _clear_all)(struct SNAME * _bitset_) \ + { \ + for (size_t i = 0; i < _bitset_->capacity; i++) \ + _bitset_->buffer[i] = 0; \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, delete); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _flip_all)(struct SNAME * _bitset_) \ + { \ + for (size_t i = 0; i < _bitset_->capacity; i++) \ + _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_bitset_, create); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _get)(struct SNAME * _bitset_, size_t bit_index) \ + { \ + /* How many bits in a word */ \ + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ +\ + cmc_bitset_word w = _bitset_->buffer[CMC_(PFX, _bit_to_index)(bit_index)]; \ +\ + return w & ((cmc_bitset_word)1 << (bit_index % bits)); \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _bitset_, size_t n_bits) \ + { \ + return CMC_(PFX, _impl_resize)(_bitset_, n_bits, true); \ + } \ +\ /* When do_resize is false, then we just want to assure that the bitset */ \ - /* can accommodate n_bits */ \ - bool CMC_(PFX, _impl_resize)(struct SNAME * _bitset_, size_t n_bits, \ - bool do_resize) \ - { \ - if (n_bits == 0) \ - { \ - _bitset_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ + /* can accommodate n_bits */ \ + bool CMC_(PFX, _impl_resize)(struct SNAME * _bitset_, size_t n_bits, bool do_resize) \ + { \ + if (n_bits == 0) \ + { \ + _bitset_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ /* -1 because n_bits is 1-based and we need to pass a 0-based index */ \ - /* +1 to have a 1-based result */ \ - size_t words = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ - \ - /* Be sure we are not always shrinking when we just want to make */ \ - /* sure that we have enough size for n_bits */ \ - if (!do_resize && words <= _bitset_->capacity) \ - return true; \ - \ - cmc_bitset_word *new_buffer = \ - realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); \ - \ - if (!new_buffer) \ - { \ - _bitset_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - _bitset_->buffer = new_buffer; \ - \ - /* Make new bits be all zeroes */ \ - if (_bitset_->capacity < words) \ - memset(_bitset_->buffer + _bitset_->capacity, 0, \ - (words - _bitset_->capacity) * sizeof(cmc_bitset_word)); \ - \ - _bitset_->capacity = words; \ - \ - if (_bitset_->callbacks && _bitset_->callbacks->resize) \ - _bitset_->callbacks->resize(); \ - \ - _bitset_->flag = CMC_FLAG_OK; \ - \ - return true; \ + /* +1 to have a 1-based result */ \ + size_t words = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ +\ + /* Be sure we are not always shrinking when we just want to make */ \ + /* sure that we have enough size for n_bits */ \ + if (!do_resize && words <= _bitset_->capacity) \ + return true; \ +\ + cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); \ +\ + if (!new_buffer) \ + { \ + _bitset_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + _bitset_->buffer = new_buffer; \ +\ + /* Make new bits be all zeroes */ \ + if (_bitset_->capacity < words) \ + memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word)); \ +\ + _bitset_->capacity = words; \ +\ + CMC_CALLBACKS_CALL(_bitset_, resize); \ +\ + _bitset_->flag = CMC_FLAG_OK; \ +\ + return true; \ } #endif /* CMC_CMC_BITSET_H */ diff --git a/src/cmc/deque.h b/src/cmc/deque.h index af92d11..3f7122f 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -43,484 +43,460 @@ /** * Core Deque implementation */ -#define CMC_CMC_DEQUE_CORE(PARAMS) \ +#define CMC_CMC_DEQUE_CORE(PARAMS) \ CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \ CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) -#define CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \ - CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \ + CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) \ - CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) \ + CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Deque Structure */ \ - struct SNAME \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ - \ - /* Current circular array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Index representing the front of the deque */ \ - size_t front; \ - \ - /* Index representing the back of the deque */ \ - size_t back; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _deque_); \ - void CMC_(PFX, _free)(struct SNAME * _deque_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _deque_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _deque_); \ - V CMC_(PFX, _back)(struct SNAME * _deque_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _deque_); \ - bool CMC_(PFX, _full)(struct SNAME * _deque_); \ - size_t CMC_(PFX, _count)(struct SNAME * _deque_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \ - int CMC_(PFX, _flag)(struct SNAME * _deque_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \ +#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* Deque Structure */ \ + struct SNAME \ + { \ + /* Dynamic circular array of elements */ \ + V *buffer; \ +\ + /* Current circular array capacity */ \ + size_t capacity; \ +\ + /* Current amount of elements */ \ + size_t count; \ +\ + /* Index representing the front of the deque */ \ + size_t front; \ +\ + /* Index representing the back of the deque */ \ + size_t back; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _deque_); \ + void CMC_(PFX, _free)(struct SNAME * _deque_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _deque_); \ + V CMC_(PFX, _back)(struct SNAME * _deque_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _deque_); \ + bool CMC_(PFX, _full)(struct SNAME * _deque_); \ + size_t CMC_(PFX, _count)(struct SNAME * _deque_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \ + int CMC_(PFX, _flag)(struct SNAME * _deque_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \ bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_deque_) \ - return NULL; \ - \ - _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_deque_->buffer) \ - { \ - alloc->free(_deque_); \ - return NULL; \ - } \ - \ - _deque_->capacity = capacity; \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - _deque_->flag = CMC_FLAG_OK; \ - _deque_->f_val = f_val; \ - _deque_->alloc = alloc; \ - _deque_->callbacks = callbacks; \ - \ - return _deque_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _deque_) \ - { \ - if (_deque_->f_val->free) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - _deque_->f_val->free(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \ - \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _deque_) \ - { \ - if (_deque_->f_val->free) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - _deque_->f_val->free(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - _deque_->alloc->free(_deque_->buffer); \ - _deque_->alloc->free(_deque_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _deque_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _deque_->alloc = &cmc_alloc_node_default; \ - else \ - _deque_->alloc = alloc; \ - \ - _deque_->callbacks = callbacks; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \ - { \ - if (CMC_(PFX, _full)(_deque_)) \ - { \ - if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ - return false; \ - } \ - \ - _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 \ - : _deque_->front - 1; \ - \ - _deque_->buffer[_deque_->front] = value; \ - \ - _deque_->count++; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->create) \ - _deque_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \ - { \ - if (CMC_(PFX, _full)(_deque_)) \ - { \ - if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ - return false; \ - } \ - \ - _deque_->buffer[_deque_->back] = value; \ - \ - _deque_->back = \ - (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ - \ - _deque_->count++; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->create) \ - _deque_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _deque_->buffer[_deque_->front] = (V){ 0 }; \ - \ - _deque_->front = (_deque_->front == _deque_->capacity - 1) \ - ? 0 \ - : _deque_->front + 1; \ - \ - _deque_->count--; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->delete) \ - _deque_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _deque_->back = \ - (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ - \ - _deque_->buffer[_deque_->back] = (V){ 0 }; \ - \ - _deque_->count--; \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->delete) \ - _deque_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _front)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return _deque_->buffer[_deque_->front]; \ - } \ - \ - V CMC_(PFX, _back)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 \ - : _deque_->back - 1]; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \ - { \ - _deque_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - \ - if (_deque_->callbacks && _deque_->callbacks->read) \ - _deque_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _deque_) \ - { \ - return _deque_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _deque_) \ - { \ - return _deque_->count >= _deque_->capacity; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _deque_) \ - { \ - return _deque_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \ - { \ - return _deque_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _deque_) \ - { \ - return _deque_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \ - { \ - _deque_->flag = CMC_FLAG_OK; \ - \ - if (_deque_->capacity == capacity) \ - goto success; \ - \ - if (capacity < _deque_->count) \ - { \ - _deque_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - { \ - _deque_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - new_buffer[j] = _deque_->buffer[i]; \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - \ - _deque_->alloc->free(_deque_->buffer); \ - \ - _deque_->buffer = new_buffer; \ - _deque_->capacity = capacity; \ - _deque_->front = 0; \ - _deque_->back = _deque_->count; \ - \ - success: \ - \ - if (_deque_->callbacks && _deque_->callbacks->resize) \ - _deque_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, \ - _deque_->alloc, _deque_->callbacks); \ - \ - if (!result) \ - { \ - _deque_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_deque_->f_val->cpy) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - else \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - result->buffer[j] = _deque_->buffer[i]; \ - \ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - \ - result->count = _deque_->count; \ - result->front = 0; \ - result->back = _deque_->count; \ - \ - _deque_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ +#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + /* None */ \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ +\ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_deque_) \ + return NULL; \ +\ + _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \ +\ + if (!_deque_->buffer) \ + { \ + alloc->free(_deque_); \ + return NULL; \ + } \ +\ + _deque_->capacity = capacity; \ + _deque_->count = 0; \ + _deque_->front = 0; \ + _deque_->back = 0; \ + _deque_->flag = CMC_FLAG_OK; \ + _deque_->f_val = f_val; \ + _deque_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_deque_, callbacks); \ +\ + return _deque_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _deque_) \ + { \ + if (_deque_->f_val->free) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + _deque_->f_val->free(_deque_->buffer[i]); \ +\ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ +\ + memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \ +\ + _deque_->count = 0; \ + _deque_->front = 0; \ + _deque_->back = 0; \ +\ + _deque_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _deque_) \ + { \ + if (_deque_->f_val->free) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + _deque_->f_val->free(_deque_->buffer[i]); \ +\ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ +\ + _deque_->alloc->free(_deque_->buffer); \ + _deque_->alloc->free(_deque_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _deque_->alloc = &cmc_alloc_node_default; \ + else \ + _deque_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_deque_, callbacks); \ +\ + _deque_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \ + { \ + if (CMC_(PFX, _full)(_deque_)) \ + { \ + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ + return false; \ + } \ +\ + _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \ +\ + _deque_->buffer[_deque_->front] = value; \ +\ + _deque_->count++; \ + _deque_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_deque_, create); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \ + { \ + if (CMC_(PFX, _full)(_deque_)) \ + { \ + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ + return false; \ + } \ +\ + _deque_->buffer[_deque_->back] = value; \ +\ + _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ +\ + _deque_->count++; \ + _deque_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_deque_, create); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + _deque_->buffer[_deque_->front] = (V){ 0 }; \ +\ + _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \ +\ + _deque_->count--; \ + _deque_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_deque_, delete); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ +\ + _deque_->buffer[_deque_->back] = (V){ 0 }; \ +\ + _deque_->count--; \ + _deque_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_deque_, delete); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _front)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _deque_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_deque_, read); \ +\ + return _deque_->buffer[_deque_->front]; \ + } \ +\ + V CMC_(PFX, _back)(struct SNAME * _deque_) \ + { \ + if (CMC_(PFX, _empty)(_deque_)) \ + { \ + _deque_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _deque_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_deque_, read); \ +\ + return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \ + { \ + _deque_->flag = CMC_FLAG_OK; \ +\ + bool result = false; \ +\ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \ + { \ + result = true; \ + break; \ + } \ +\ + i = (i + 1) % _deque_->capacity; \ + } \ +\ + CMC_CALLBACKS_CALL(_deque_, read); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _deque_) \ + { \ + return _deque_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _deque_) \ + { \ + return _deque_->count >= _deque_->capacity; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _deque_) \ + { \ + return _deque_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \ + { \ + return _deque_->capacity; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _deque_) \ + { \ + return _deque_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \ + { \ + _deque_->flag = CMC_FLAG_OK; \ +\ + if (_deque_->capacity == capacity) \ + goto success; \ +\ + if (capacity < _deque_->count) \ + { \ + _deque_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \ +\ + if (!new_buffer) \ + { \ + _deque_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + new_buffer[j] = _deque_->buffer[i]; \ +\ + i = (i + 1) % _deque_->capacity; \ + } \ +\ + _deque_->alloc->free(_deque_->buffer); \ +\ + _deque_->buffer = new_buffer; \ + _deque_->capacity = capacity; \ + _deque_->front = 0; \ + _deque_->back = _deque_->count; \ +\ + success: \ +\ + CMC_CALLBACKS_CALL(_deque_, resize); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, _deque_->alloc, NULL); \ +\ + if (!result) \ + { \ + _deque_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _deque_->callbacks); \ +\ + if (_deque_->f_val->cpy) \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \ +\ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ + else \ + { \ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + result->buffer[j] = _deque_->buffer[i]; \ +\ + i = (i + 1) % _deque_->capacity; \ + } \ + } \ +\ + result->count = _deque_->count; \ + result->front = 0; \ + result->back = _deque_->count; \ +\ + _deque_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \ - { \ - _deque1_->flag = CMC_FLAG_OK; \ - _deque2_->flag = CMC_FLAG_OK; \ - \ - if (_deque1_->count != _deque2_->count) \ - return false; \ - \ - size_t i, j, k; \ - for (i = _deque1_->front, j = _deque2_->front, k = 0; \ - k < _deque1_->count; k++) \ - { \ - if (_deque1_->f_val->cmp(_deque1_->buffer[i], \ - _deque2_->buffer[j]) != 0) \ - return false; \ - \ - i = (i + 1) % _deque1_->capacity; \ - j = (j + 1) % _deque2_->capacity; \ - } \ - \ - return true; \ + { \ + _deque1_->flag = CMC_FLAG_OK; \ + _deque2_->flag = CMC_FLAG_OK; \ +\ + if (_deque1_->count != _deque2_->count) \ + return false; \ +\ + size_t i, j, k; \ + for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; k++) \ + { \ + if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) \ + return false; \ +\ + i = (i + 1) % _deque1_->capacity; \ + j = (j + 1) % _deque2_->capacity; \ + } \ +\ + return true; \ } #endif /* CMC_CMC_DEQUE_H */ diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index cbafa1f..d605142 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -55,1418 +55,1359 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " /** * Core HashBidiMap implementation */ -#define CMC_CMC_HASHBIDIMAP_CORE(PARAMS) \ +#define CMC_CMC_HASHBIDIMAP_CORE(PARAMS) \ CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \ CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHBIDIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ - \ - /* HashBidiMap Structure */ \ - struct SNAME \ - { \ - /* Array 0 is K -> V and array 1 is V -> K */ \ - struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ - \ - /* Current arrays capacity */ \ - size_t capacity; \ - \ - /* Current amount of keys */ \ - size_t count; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - \ - /* Methods */ \ - /* Returns an iterator to the start of the hashbidimap */ \ - struct CMC_DEF_ITER(SNAME) (*it_start)(struct SNAME *); \ - \ - /* Returns an iterator to the end of the hashbidimap */ \ - struct CMC_DEF_ITER(SNAME) (*it_end)(struct SNAME *); \ - }; \ - \ - /* HashBidiMap Entry */ \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry Key */ \ - K key; \ - \ - /* Entry Value */ \ - V value; \ - \ - /* The distance of this node to its original position */ \ - /* dist[0] is relative to K -> V */ \ - /* dist[1] is relative to V -> K */ \ - size_t dist[2]; \ - \ - /* References to this node in the hashbidimap buffer. Used to */ \ - /* prevent searching for this node twice for update() and */ \ - /* remove(). Increases memory overhead but reduces execution time */ \ - /* ref[0] is relative to K -> V */ \ - /* ref[1] is relative to V -> K */ \ - struct CMC_DEF_ENTRY(SNAME) * *ref[2]; \ - }; \ - \ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(K); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(K); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(K); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(K); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(K); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(K); \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* HashBidiMap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target hashbidimap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_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); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key); \ - bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val); \ - bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, \ - V * out_val); \ - bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, \ - V * out_val); \ - /* Element Access */ \ - K CMC_(PFX, _get_key)(struct SNAME * _map_, V val); \ - V CMC_(PFX, _get_val)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - bool CMC_(PFX, _full)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ - double CMC_(PFX, _load)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Allocation and Deallocation */ \ +#define CMC_CMC_HASHBIDIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ +\ + /* HashBidiMap Structure */ \ + struct SNAME \ + { \ + /* Array 0 is K -> V and array 1 is V -> K */ \ + struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ +\ + /* Current arrays capacity */ \ + size_t capacity; \ +\ + /* Current amount of keys */ \ + size_t count; \ +\ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Key function table */ \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ +\ + /* Methods */ \ + /* Returns an iterator to the start of the hashbidimap */ \ + struct CMC_DEF_ITER(SNAME) (*it_start)(struct SNAME *); \ +\ + /* Returns an iterator to the end of the hashbidimap */ \ + struct CMC_DEF_ITER(SNAME) (*it_end)(struct SNAME *); \ + }; \ +\ + /* HashBidiMap Entry */ \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry Key */ \ + K key; \ +\ + /* Entry Value */ \ + V value; \ +\ + /* The distance of this node to its original position */ \ + /* dist[0] is relative to K -> V */ \ + /* dist[1] is relative to V -> K */ \ + size_t dist[2]; \ +\ + /* References to this node in the hashbidimap buffer. Used to */ \ + /* prevent searching for this node twice for update() and */ \ + /* remove(). Increases memory overhead but reduces execution time */ \ + /* ref[0] is relative to K -> V */ \ + /* ref[1] is relative to V -> K */ \ + struct CMC_DEF_ENTRY(SNAME) * *ref[2]; \ + }; \ +\ + /* Key struct function table */ \ + struct CMC_DEF_FKEY(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(K); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(K); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(K); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(K); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(K); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(K); \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* HashBidiMap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target hashbidimap */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* The index of the first element */ \ + size_t first; \ +\ + /* The index of the last element */ \ + size_t last; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key); \ + bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val); \ + bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, V * out_val); \ + bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, V * out_val); \ + /* Element Access */ \ + K CMC_(PFX, _get_key)(struct SNAME * _map_, V val); \ + V CMC_(PFX, _get_val)(struct SNAME * _map_, K key); \ + /* Collection State */ \ + bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + bool CMC_(PFX, _full)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ + double CMC_(PFX, _load)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ +\ + /* Iterator Functions */ \ + /* Iterator Allocation and Deallocation */ \ struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target); \ - void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Initialization */ \ - void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, \ - struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Initialization */ \ + void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ - \ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_add_entry_to_key)( \ - struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_add_entry_to_val)( \ - struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ - static struct CMC_DEF_ITER(SNAME) \ - CMC_(PFX, _impl_it_start)(struct SNAME * _map_); \ - static struct CMC_DEF_ITER(SNAME) \ - CMC_(PFX, _impl_it_end)(struct SNAME * _map_); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_key || !f_val) \ - return NULL; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->buffer = alloc->calloc( \ - real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ - \ - if (!_map_->buffer) \ - { \ - alloc->free(_map_->buffer); \ - alloc->free(_map_); \ - return NULL; \ - } \ - \ - _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 = NULL; \ - _map_->it_start = CMC_(PFX, _impl_it_start); \ - _map_->it_end = CMC_(PFX, _impl_it_end); \ - \ - return _map_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_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) \ - { \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_key || !f_val) \ - return NULL; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->buffer = alloc->calloc( \ - real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ - \ - if (!_map_->buffer) \ - { \ - alloc->free(_map_->buffer); \ - alloc->free(_map_); \ - return NULL; \ - } \ - \ - _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_->flag = CMC_FLAG_OK; \ - _map_->alloc = alloc; \ - _map_->callbacks = callbacks; \ - _map_->it_start = CMC_(PFX, _impl_it_start); \ - _map_->it_end = CMC_(PFX, _impl_it_end); \ - \ - return _map_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _map_) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i][0]; \ - \ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(entry->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(entry->value); \ - \ - _map_->alloc->free(entry); \ - } \ - \ - _map_->buffer[i][0] = NULL; \ - _map_->buffer[i][1] = NULL; \ - } \ - \ - _map_->count = 0; \ - _map_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _map_) \ - { \ - CMC_(PFX, _clear)(_map_); \ - \ - _map_->alloc->free(_map_->buffer); \ - _map_->alloc->free(_map_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ - \ - _map_->callbacks = callbacks; \ - \ - _map_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ - { \ - if (CMC_(PFX, _full)(_map_)) \ - { \ - if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ - return false; \ - } \ - \ - if (CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL || \ - CMC_(PFX, _impl_get_entry_by_val)(_map_, value) != NULL) \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_new_entry)(_map_, key, value); \ - \ - struct CMC_DEF_ENTRY(SNAME) **key_entry = \ - CMC_(PFX, _impl_add_entry_to_key)(_map_, entry); \ - struct CMC_DEF_ENTRY(SNAME) **val_entry = \ - CMC_(PFX, _impl_add_entry_to_val)(_map_, entry); \ - \ - if (!key_entry || !val_entry) \ - { \ - if (key_entry) \ - *key_entry = CMC_ENTRY_DELETED; \ - if (val_entry) \ - *val_entry = CMC_ENTRY_DELETED; \ - \ - _map_->alloc->free(entry); \ - \ - _map_->flag = CMC_FLAG_ERROR; \ - \ - return false; \ - } \ - \ - _map_->count++; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ - \ - val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ - \ - if (!val_entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - /* The mapping val -> new_key is already true */ \ - if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) \ - goto success; \ - \ - if (CMC_(PFX, _impl_get_entry_by_key)(_map_, new_key) != NULL) \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - \ - key_entry = (*val_entry)->ref[0]; \ - \ - if (!key_entry || *key_entry != *val_entry) \ - { \ - /* Should never happen */ \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - /* Remove entry from key buffer and add it again with new key */ \ - struct CMC_DEF_ENTRY(SNAME) *to_add = *key_entry; \ - K tmp_key = to_add->key; \ - to_add->key = new_key; \ - \ - *key_entry = CMC_ENTRY_DELETED; \ - \ - if (!CMC_(PFX, _impl_add_entry_to_key)(_map_, to_add)) \ - { \ - /* Revert changes */ \ - to_add->key = tmp_key; \ - *key_entry = to_add; \ - \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - success: \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ - \ - key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ - \ - if (!key_entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - /* The mapping key -> new_val is already true */ \ - if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) \ - goto success; \ - \ - if (CMC_(PFX, _impl_get_entry_by_val)(_map_, new_val) != NULL) \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - \ - val_entry = (*key_entry)->ref[1]; \ - \ - if (!val_entry || *val_entry != *key_entry) \ - { \ - /* Should never happen */ \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - /* Remove entry from value buffer and add it again with new value */ \ - struct CMC_DEF_ENTRY(SNAME) *to_add = *val_entry; \ - V tmp_val = to_add->value; \ - to_add->value = new_val; \ - \ - *val_entry = CMC_ENTRY_DELETED; \ - \ - if (!CMC_(PFX, _impl_add_entry_to_val)(_map_, to_add)) \ - { \ - /* Revert changes */ \ - to_add->value = tmp_val; \ - *val_entry = to_add; \ - \ - _map_->flag = CMC_FLAG_ERROR; \ - \ - return false; \ - } \ - \ - success: \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, \ - V * out_val) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ - \ - key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ - \ - if (!key_entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - val_entry = (*key_entry)->ref[1]; \ - \ - if (!val_entry || *val_entry != *key_entry) \ - { \ - /* Should never happen */ \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - if (out_key) \ - *out_key = (*key_entry)->key; \ - if (out_val) \ - *out_val = (*key_entry)->value; \ - \ - _map_->alloc->free(*key_entry); \ - \ - *key_entry = CMC_ENTRY_DELETED; \ - *val_entry = CMC_ENTRY_DELETED; \ - \ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, \ - V * out_val) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ - \ - val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ - \ - if (!val_entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - key_entry = (*val_entry)->ref[0]; \ - \ - if (!key_entry || *key_entry != *val_entry) \ - { \ - /* Should never happen */ \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - if (out_key) \ - *out_key = (*val_entry)->key; \ - if (out_val) \ - *out_val = (*val_entry)->value; \ - \ - _map_->alloc->free(*val_entry); \ - \ - *key_entry = CMC_ENTRY_DELETED; \ - *val_entry = CMC_ENTRY_DELETED; \ - \ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - K CMC_(PFX, _get_key)(struct SNAME * _map_, V val) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **entry = \ - CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ - \ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return (*entry)->key; \ - } \ - \ - V CMC_(PFX, _get_val)(struct SNAME * _map_, K key) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **entry = \ - CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return (*entry)->value; \ - } \ - \ - bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key) \ - { \ - _map_->flag = CMC_FLAG_OK; \ - \ - bool result = CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val) \ - { \ - _map_->flag = CMC_FLAG_OK; \ - \ - bool result = CMC_(PFX, _impl_get_entry_by_val)(_map_, val) != NULL; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _map_) \ - { \ - return _map_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _map_) \ - { \ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _map_) \ - { \ - return _map_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ - { \ - return _map_->capacity; \ - } \ - \ - double CMC_(PFX, _load)(struct SNAME * _map_) \ - { \ - return _map_->load; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _map_) \ - { \ - return _map_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ - { \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->capacity == capacity) \ - goto success; \ - \ - if (_map_->capacity > capacity / _map_->load) \ - goto success; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _map_->load) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - /* Calculate required capacity based on the prime numbers */ \ - size_t new_cap = CMC_(PFX, _impl_calculate_size)(capacity); \ - \ - /* Not possible to shrink with current available prime numbers */ \ - if (new_cap < _map_->count / _map_->load) \ - { \ - _map_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - /* No callbacks since _new_map_ is just a temporary hashtable */ \ - struct SNAME *_new_map_ = \ - CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ - \ - if (!_new_map_) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ - \ - if (scan && scan != CMC_ENTRY_DELETED) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **e1 = \ - CMC_(PFX, _impl_add_entry_to_key)(_new_map_, scan); \ - struct CMC_DEF_ENTRY(SNAME) **e2 = \ - CMC_(PFX, _impl_add_entry_to_val)(_new_map_, scan); \ - \ - if (!e1 || !e2) \ - { \ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ - _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ - \ - _map_->alloc->free(_new_map_->buffer); \ - _map_->alloc->free(_new_map_); \ - \ - _map_->flag = CMC_FLAG_ERROR; \ - \ - return false; \ - } \ - \ - _new_map_->count++; \ - } \ - } \ - \ - if (_map_->count != _new_map_->count) \ - { \ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ - _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ - \ - _map_->alloc->free(_new_map_->buffer); \ - _map_->alloc->free(_new_map_); \ - \ - _map_->flag = CMC_FLAG_ERROR; \ - \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) * (*tmp_buff)[2] = _map_->buffer; \ - \ - _map_->buffer = _new_map_->buffer; \ - _map_->capacity = _new_map_->capacity; \ - \ - _map_->alloc->free(tmp_buff); \ - _map_->alloc->free(_new_map_); \ - \ - success: \ - \ - if (_map_->callbacks && _map_->callbacks->resize) \ - _map_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ - { \ - /* TODO this function can be optimized */ \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _map_->capacity * _map_->load, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, _map_->callbacks); \ - \ - if (!result) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ - \ - if (scan && scan != CMC_ENTRY_DELETED) \ - { \ - K tmp_key; \ - V tmp_val; \ - \ - if (_map_->f_key->cpy) \ - tmp_key = _map_->f_key->cpy(scan->key); \ - else \ - tmp_key = scan->key; \ - \ - if (_map_->f_val->cpy) \ - tmp_val = _map_->f_val->cpy(scan->value); \ - else \ - tmp_val = scan->value; \ - \ - /* TODO treat the possible errors */ \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_new_entry)(result, tmp_key, tmp_val); \ - \ - CMC_(PFX, _impl_add_entry_to_key)(result, entry); \ - CMC_(PFX, _impl_add_entry_to_val)(result, entry); \ - \ - result->count++; \ - } \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ - { \ - _map1_->flag = CMC_FLAG_OK; \ - _map2_->flag = CMC_FLAG_OK; \ - \ - if (_map1_->count != _map2_->count) \ - return false; \ - \ - struct SNAME *_mapA_; \ - struct SNAME *_mapB_; \ - \ - if (_map1_->capacity < _map2_->capacity) \ - { \ - _mapA_ = _map1_; \ - _mapB_ = _map2_; \ - } \ - else \ - { \ - _mapA_ = _map2_; \ - _mapB_ = _map1_; \ - } \ - \ - for (size_t i = 0; i < _mapA_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _mapA_->buffer[i][0]; \ - \ - if (scan && scan != CMC_ENTRY_DELETED) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **entry_B = \ - CMC_(PFX, _impl_get_entry_by_key)(_mapB_, scan->key); \ - \ - if (!entry_B) \ - return false; \ - \ - if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) \ - return false; \ - } \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ - \ - int n = snprintf( \ - str.s, cmc_string_len, cmc_cmc_string_fmt_hashbidimap, #SNAME, #K, \ - #V, m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, \ - m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[i][0]; \ - \ - if (target && target != CMC_ENTRY_DELETED) \ - { \ - if (!_map_->f_key->str(fptr, target->key) || \ - !_map_->f_val->str(fptr, target->value)) \ - return false; \ - } \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) *iter = \ - target->alloc->malloc(sizeof(struct CMC_DEF_ITER(SNAME))); \ - \ - if (!iter) \ - return NULL; \ - \ - CMC_(PFX, _iter_init)(iter, target); \ - \ - return iter; \ - } \ - \ - void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - iter->target->alloc->free(iter); \ - } \ - \ - void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, \ - struct SNAME * target) \ - { \ - memset(iter, 0, sizeof(struct CMC_DEF_ITER(SNAME))); \ - \ - iter->target = target; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ - \ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter->first = i; \ - break; \ - } \ - } \ - \ - iter->cursor = iter->first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ +#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ +\ + /* Implementation Detail Functions */ \ + static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \ + static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key); \ + static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_add_entry_to_key)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_add_entry_to_val)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ + static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_start)(struct SNAME * _map_); \ + static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_end)(struct SNAME * _map_); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + struct CMC_ALLOC_NODE_NAME *alloc = &cmc_alloc_node_default; \ +\ + if (capacity == 0 || load <= 0 || load >= 1) \ + return NULL; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ +\ + if (!f_key || !f_val) \ + return NULL; \ +\ + size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ +\ + struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_map_) \ + return NULL; \ +\ + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ +\ + if (!_map_->buffer) \ + { \ + alloc->free(_map_->buffer); \ + alloc->free(_map_); \ + return NULL; \ + } \ +\ + _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; \ + CMC_CALLBACKS_ASSIGN(_map_, NULL); \ + _map_->it_start = CMC_(PFX, _impl_it_start); \ + _map_->it_end = CMC_(PFX, _impl_it_end); \ +\ + return _map_; \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity == 0 || load <= 0 || load >= 1) \ + return NULL; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ +\ + if (!f_key || !f_val) \ + return NULL; \ +\ + size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_map_) \ + return NULL; \ +\ + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ +\ + if (!_map_->buffer) \ + { \ + alloc->free(_map_->buffer); \ + alloc->free(_map_); \ + return NULL; \ + } \ +\ + _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_->flag = CMC_FLAG_OK; \ + _map_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ + _map_->it_start = CMC_(PFX, _impl_it_start); \ + _map_->it_end = CMC_(PFX, _impl_it_end); \ +\ + return _map_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _map_) \ + { \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i][0]; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + if (_map_->f_key->free) \ + _map_->f_key->free(entry->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(entry->value); \ +\ + _map_->alloc->free(entry); \ + } \ +\ + _map_->buffer[i][0] = NULL; \ + _map_->buffer[i][1] = NULL; \ + } \ +\ + _map_->count = 0; \ + _map_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _map_) \ + { \ + CMC_(PFX, _clear)(_map_); \ +\ + _map_->alloc->free(_map_->buffer); \ + _map_->alloc->free(_map_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _map_->alloc = &cmc_alloc_node_default; \ + else \ + _map_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ +\ + _map_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ + { \ + if (CMC_(PFX, _full)(_map_)) \ + { \ + if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ + return false; \ + } \ +\ + if (CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL || \ + CMC_(PFX, _impl_get_entry_by_val)(_map_, value) != NULL) \ + { \ + _map_->flag = CMC_FLAG_DUPLICATE; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(_map_, key, value); \ +\ + struct CMC_DEF_ENTRY(SNAME) **key_entry = CMC_(PFX, _impl_add_entry_to_key)(_map_, entry); \ + struct CMC_DEF_ENTRY(SNAME) **val_entry = CMC_(PFX, _impl_add_entry_to_val)(_map_, entry); \ +\ + if (!key_entry || !val_entry) \ + { \ + if (key_entry) \ + *key_entry = CMC_ENTRY_DELETED; \ + if (val_entry) \ + *val_entry = CMC_ENTRY_DELETED; \ +\ + _map_->alloc->free(entry); \ +\ + _map_->flag = CMC_FLAG_ERROR; \ +\ + return false; \ + } \ +\ + _map_->count++; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->create) \ + _map_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ +\ + val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ +\ + if (!val_entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + /* The mapping val -> new_key is already true */ \ + if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) \ + goto success; \ +\ + if (CMC_(PFX, _impl_get_entry_by_key)(_map_, new_key) != NULL) \ + { \ + _map_->flag = CMC_FLAG_DUPLICATE; \ + return false; \ + } \ +\ + key_entry = (*val_entry)->ref[0]; \ +\ + if (!key_entry || *key_entry != *val_entry) \ + { \ + /* Should never happen */ \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + /* Remove entry from key buffer and add it again with new key */ \ + struct CMC_DEF_ENTRY(SNAME) *to_add = *key_entry; \ + K tmp_key = to_add->key; \ + to_add->key = new_key; \ +\ + *key_entry = CMC_ENTRY_DELETED; \ +\ + if (!CMC_(PFX, _impl_add_entry_to_key)(_map_, to_add)) \ + { \ + /* Revert changes */ \ + to_add->key = tmp_key; \ + *key_entry = to_add; \ +\ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + success: \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ +\ + key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ +\ + if (!key_entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + /* The mapping key -> new_val is already true */ \ + if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) \ + goto success; \ +\ + if (CMC_(PFX, _impl_get_entry_by_val)(_map_, new_val) != NULL) \ + { \ + _map_->flag = CMC_FLAG_DUPLICATE; \ + return false; \ + } \ +\ + val_entry = (*key_entry)->ref[1]; \ +\ + if (!val_entry || *val_entry != *key_entry) \ + { \ + /* Should never happen */ \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + /* Remove entry from value buffer and add it again with new value */ \ + struct CMC_DEF_ENTRY(SNAME) *to_add = *val_entry; \ + V tmp_val = to_add->value; \ + to_add->value = new_val; \ +\ + *val_entry = CMC_ENTRY_DELETED; \ +\ + if (!CMC_(PFX, _impl_add_entry_to_val)(_map_, to_add)) \ + { \ + /* Revert changes */ \ + to_add->value = tmp_val; \ + *val_entry = to_add; \ +\ + _map_->flag = CMC_FLAG_ERROR; \ +\ + return false; \ + } \ +\ + success: \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, V * out_val) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ +\ + key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ +\ + if (!key_entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + val_entry = (*key_entry)->ref[1]; \ +\ + if (!val_entry || *val_entry != *key_entry) \ + { \ + /* Should never happen */ \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + if (out_key) \ + *out_key = (*key_entry)->key; \ + if (out_val) \ + *out_val = (*key_entry)->value; \ +\ + _map_->alloc->free(*key_entry); \ +\ + *key_entry = CMC_ENTRY_DELETED; \ + *val_entry = CMC_ENTRY_DELETED; \ +\ + _map_->count--; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, V * out_val) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ +\ + val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ +\ + if (!val_entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + key_entry = (*val_entry)->ref[0]; \ +\ + if (!key_entry || *key_entry != *val_entry) \ + { \ + /* Should never happen */ \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + if (out_key) \ + *out_key = (*val_entry)->key; \ + if (out_val) \ + *out_val = (*val_entry)->value; \ +\ + _map_->alloc->free(*val_entry); \ +\ + *key_entry = CMC_ENTRY_DELETED; \ + *val_entry = CMC_ENTRY_DELETED; \ +\ + _map_->count--; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + K CMC_(PFX, _get_key)(struct SNAME * _map_, V val) \ + { \ + struct CMC_DEF_ENTRY(SNAME) **entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ +\ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return (V){ 0 }; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return (*entry)->key; \ + } \ +\ + V CMC_(PFX, _get_val)(struct SNAME * _map_, K key) \ + { \ + struct CMC_DEF_ENTRY(SNAME) **entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ +\ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return (V){ 0 }; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return (*entry)->value; \ + } \ +\ + bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key) \ + { \ + _map_->flag = CMC_FLAG_OK; \ +\ + bool result = CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val) \ + { \ + _map_->flag = CMC_FLAG_OK; \ +\ + bool result = CMC_(PFX, _impl_get_entry_by_val)(_map_, val) != NULL; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _map_) \ + { \ + return _map_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _map_) \ + { \ + return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _map_) \ + { \ + return _map_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ + { \ + return _map_->capacity; \ + } \ +\ + double CMC_(PFX, _load)(struct SNAME * _map_) \ + { \ + return _map_->load; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _map_) \ + { \ + return _map_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ + { \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->capacity == capacity) \ + goto success; \ +\ + if (_map_->capacity > capacity / _map_->load) \ + goto success; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * _map_->load) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + /* Calculate required capacity based on the prime numbers */ \ + size_t new_cap = CMC_(PFX, _impl_calculate_size)(capacity); \ +\ + /* Not possible to shrink with current available prime numbers */ \ + if (new_cap < _map_->count / _map_->load) \ + { \ + _map_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + /* No callbacks since _new_map_ is just a temporary hashtable */ \ + struct SNAME *_new_map_ = \ + CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ +\ + if (!_new_map_) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ +\ + if (scan && scan != CMC_ENTRY_DELETED) \ + { \ + struct CMC_DEF_ENTRY(SNAME) **e1 = CMC_(PFX, _impl_add_entry_to_key)(_new_map_, scan); \ + struct CMC_DEF_ENTRY(SNAME) **e2 = CMC_(PFX, _impl_add_entry_to_val)(_new_map_, scan); \ +\ + if (!e1 || !e2) \ + { \ + /* Prevent the map from freeing the data */ \ + _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ + _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ +\ + _map_->alloc->free(_new_map_->buffer); \ + _map_->alloc->free(_new_map_); \ +\ + _map_->flag = CMC_FLAG_ERROR; \ +\ + return false; \ + } \ +\ + _new_map_->count++; \ + } \ + } \ +\ + if (_map_->count != _new_map_->count) \ + { \ + /* Prevent the map from freeing the data */ \ + _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ + _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ +\ + _map_->alloc->free(_new_map_->buffer); \ + _map_->alloc->free(_new_map_); \ +\ + _map_->flag = CMC_FLAG_ERROR; \ +\ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) * (*tmp_buff)[2] = _map_->buffer; \ +\ + _map_->buffer = _new_map_->buffer; \ + _map_->capacity = _new_map_->capacity; \ +\ + _map_->alloc->free(tmp_buff); \ + _map_->alloc->free(_new_map_); \ +\ + success: \ +\ + if (_map_->callbacks && _map_->callbacks->resize) \ + _map_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ + { \ + /* TODO this function can be optimized */ \ + struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, NULL); \ +\ + if (!result) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ +\ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ +\ + if (scan && scan != CMC_ENTRY_DELETED) \ + { \ + K tmp_key; \ + V tmp_val; \ +\ + if (_map_->f_key->cpy) \ + tmp_key = _map_->f_key->cpy(scan->key); \ + else \ + tmp_key = scan->key; \ +\ + if (_map_->f_val->cpy) \ + tmp_val = _map_->f_val->cpy(scan->value); \ + else \ + tmp_val = scan->value; \ +\ + /* TODO treat the possible errors */ \ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(result, tmp_key, tmp_val); \ +\ + CMC_(PFX, _impl_add_entry_to_key)(result, entry); \ + CMC_(PFX, _impl_add_entry_to_val)(result, entry); \ +\ + result->count++; \ + } \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ + { \ + _map1_->flag = CMC_FLAG_OK; \ + _map2_->flag = CMC_FLAG_OK; \ +\ + if (_map1_->count != _map2_->count) \ + return false; \ +\ + struct SNAME *_mapA_; \ + struct SNAME *_mapB_; \ +\ + if (_map1_->capacity < _map2_->capacity) \ + { \ + _mapA_ = _map1_; \ + _mapB_ = _map2_; \ + } \ + else \ + { \ + _mapA_ = _map2_; \ + _mapB_ = _map1_; \ + } \ +\ + for (size_t i = 0; i < _mapA_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _mapA_->buffer[i][0]; \ +\ + if (scan && scan != CMC_ENTRY_DELETED) \ + { \ + struct CMC_DEF_ENTRY(SNAME) **entry_B = CMC_(PFX, _impl_get_entry_by_key)(_mapB_, scan->key); \ +\ + if (!entry_B) \ + return false; \ +\ + if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) \ + return false; \ + } \ + } \ +\ + return true; \ + } \ +\ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ + { \ + struct cmc_string str; \ + struct SNAME *m_ = _map_; \ +\ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashbidimap, #SNAME, #K, #V, m_, m_->buffer, \ + m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ +\ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ + { \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[i][0]; \ +\ + if (target && target != CMC_ENTRY_DELETED) \ + { \ + if (!_map_->f_key->str(fptr, target->key) || !_map_->f_val->str(fptr, target->value)) \ + return false; \ + } \ + } \ +\ + return true; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) *iter = target->alloc->malloc(sizeof(struct CMC_DEF_ITER(SNAME))); \ +\ + if (!iter) \ + return NULL; \ +\ + CMC_(PFX, _iter_init)(iter, target); \ +\ + return iter; \ + } \ +\ + void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + iter->target->alloc->free(iter); \ + } \ +\ + void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, struct SNAME * target) \ + { \ + memset(iter, 0, sizeof(struct CMC_DEF_ITER(SNAME))); \ +\ + iter->target = target; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter->first = i; \ + break; \ + } \ + } \ +\ + iter->cursor = iter->first; \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][0]; \ - \ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter->last = i - 1; \ - break; \ - } \ - } \ - } \ - } \ - \ - bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ - } \ - } \ - \ - void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = false; \ - iter->end = true; \ - } \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - iter->target->buffer[iter->cursor][0]; \ - \ - iter->index++; \ - \ - while (1) \ - { \ - iter->cursor++; \ - scan = iter->target->buffer[iter->cursor][0]; \ - \ - if (scan != NULL && scan != CMC_ENTRY_DELETED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - iter->target->buffer[iter->cursor][0]; \ - \ - iter->index--; \ - \ - while (1) \ - { \ - iter->cursor--; \ - scan = iter->target->buffer[iter->cursor][0]; \ - \ - if (scan != NULL && scan != CMC_ENTRY_DELETED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at */ \ - /* the given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->target->flag = CMC_FLAG_EMPTY; \ - return (K){ 0 }; \ - } \ - \ - return iter->target->buffer[iter->cursor][0]->key; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->target->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - return iter->target->buffer[iter->cursor][0]->value; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \ - \ - if (!entry) \ - return NULL; \ - \ - entry->key = key; \ - entry->value = value; \ - entry->dist[0] = 0; \ - entry->dist[1] = 0; \ - entry->ref[0] = NULL; \ - entry->ref[1] = NULL; \ - \ - return entry; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - size_t pos = hash % _map_->capacity; \ - \ - struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][0]; \ - \ - while (target != NULL) \ - { \ - if (target != CMC_ENTRY_DELETED && \ - _map_->f_key->cmp(target->key, key) == 0) \ - return &(_map_->buffer[pos % _map_->capacity][0]); \ - \ - pos++; \ - target = _map_->buffer[pos % _map_->capacity][0]; \ - } \ - \ - return NULL; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val) \ - { \ - size_t hash = _map_->f_val->hash(val); \ - size_t pos = hash % _map_->capacity; \ - \ - struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][1]; \ - \ - while (target != NULL) \ - { \ - if (target != CMC_ENTRY_DELETED && \ - _map_->f_val->cmp(target->value, val) == 0) \ - return &(_map_->buffer[pos % _map_->capacity][1]); \ - \ - pos++; \ - target = _map_->buffer[pos % _map_->capacity][1]; \ - } \ - \ - return NULL; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_add_entry_to_key)( \ - struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \ - \ - size_t hash = _map_->f_key->hash(entry->key); \ - size_t original_pos = hash % _map_->capacity; \ - size_t pos = original_pos; \ - \ - struct CMC_DEF_ENTRY(SNAME) **scan = \ - &(_map_->buffer[hash % _map_->capacity][0]); \ - \ - if (*scan == NULL) \ - { \ - *scan = entry; \ - \ - entry->ref[0] = scan; \ - \ - return scan; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - scan = &(_map_->buffer[pos % _map_->capacity][0]); \ - \ - if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \ - { \ - if (!to_return) \ - to_return = scan; \ - \ - *scan = entry; \ - entry->ref[0] = scan; \ - entry->dist[0] = pos - original_pos; \ - \ - return to_return; \ - } \ - else if ((*scan)->dist[0] < pos - original_pos) \ - { \ - if (!to_return) \ - to_return = scan; \ - \ - size_t tmp_dist = (*scan)->dist[0]; \ - entry->dist[0] = pos - original_pos; \ - original_pos = pos - tmp_dist; \ - \ - entry->ref[0] = scan; \ - \ - struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \ - *scan = entry; \ - entry = _tmp_; \ - } \ - } \ - } \ - \ - return NULL; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_add_entry_to_val)( \ - struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \ - \ - size_t hash = _map_->f_val->hash(entry->value); \ - size_t original_pos = hash % _map_->capacity; \ - size_t pos = original_pos; \ - \ - struct CMC_DEF_ENTRY(SNAME) **scan = \ - &(_map_->buffer[hash % _map_->capacity][1]); \ - \ - if (*scan == NULL) \ - { \ - *scan = entry; \ - \ - entry->ref[1] = scan; \ - \ - return scan; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - scan = &(_map_->buffer[pos % _map_->capacity][1]); \ - \ - if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \ - { \ - if (!to_return) \ - to_return = scan; \ - \ - *scan = entry; \ - entry->ref[1] = scan; \ - entry->dist[1] = pos - original_pos; \ - \ - return to_return; \ - } \ - else if ((*scan)->dist[1] < pos - original_pos) \ - { \ - if (!to_return) \ - to_return = scan; \ - \ - size_t tmp_dist = (*scan)->dist[1]; \ - entry->dist[1] = pos - original_pos; \ - original_pos = pos - tmp_dist; \ - \ - entry->ref[1] = scan; \ - \ - struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \ - *scan = entry; \ - entry = _tmp_; \ - } \ - } \ - } \ - \ - return NULL; \ - } \ - \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = \ - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ - \ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ - \ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ - \ - return cmc_hashtable_primes[i]; \ - } \ - \ - static struct CMC_DEF_ITER(SNAME) \ - CMC_(PFX, _impl_it_start)(struct SNAME * _map_) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - CMC_(PFX, _iter_init)(&iter, _map_); \ - \ - return iter; \ - } \ - \ - static struct CMC_DEF_ITER(SNAME) \ - CMC_(PFX, _impl_it_end)(struct SNAME * _map_) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - CMC_(PFX, _iter_init)(&iter, _map_); \ - CMC_(PFX, _iter_to_end)(&iter); \ - \ - return iter; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter->last = i - 1; \ + break; \ + } \ + } \ + } \ + } \ +\ + bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = false; \ + } \ + } \ +\ + void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = false; \ + iter->end = true; \ + } \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + struct CMC_DEF_ENTRY(SNAME) *scan = iter->target->buffer[iter->cursor][0]; \ +\ + iter->index++; \ +\ + while (1) \ + { \ + iter->cursor++; \ + scan = iter->target->buffer[iter->cursor][0]; \ +\ + if (scan != NULL && scan != CMC_ENTRY_DELETED) \ + break; \ + } \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + struct CMC_DEF_ENTRY(SNAME) *scan = iter->target->buffer[iter->cursor][0]; \ +\ + iter->index--; \ +\ + while (1) \ + { \ + iter->cursor--; \ + scan = iter->target->buffer[iter->cursor][0]; \ +\ + if (scan != NULL && scan != CMC_ENTRY_DELETED) \ + break; \ + } \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at */ \ + /* the given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->target->flag = CMC_FLAG_EMPTY; \ + return (K){ 0 }; \ + } \ +\ + return iter->target->buffer[iter->cursor][0]->key; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->target->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + return iter->target->buffer[iter->cursor][0]->value; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \ +\ + if (!entry) \ + return NULL; \ +\ + entry->key = key; \ + entry->value = value; \ + entry->dist[0] = 0; \ + entry->dist[1] = 0; \ + entry->ref[0] = NULL; \ + entry->ref[1] = NULL; \ +\ + return entry; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key) \ + { \ + size_t hash = _map_->f_key->hash(key); \ + size_t pos = hash % _map_->capacity; \ +\ + struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][0]; \ +\ + while (target != NULL) \ + { \ + if (target != CMC_ENTRY_DELETED && _map_->f_key->cmp(target->key, key) == 0) \ + return &(_map_->buffer[pos % _map_->capacity][0]); \ +\ + pos++; \ + target = _map_->buffer[pos % _map_->capacity][0]; \ + } \ +\ + return NULL; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val) \ + { \ + size_t hash = _map_->f_val->hash(val); \ + size_t pos = hash % _map_->capacity; \ +\ + struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][1]; \ +\ + while (target != NULL) \ + { \ + if (target != CMC_ENTRY_DELETED && _map_->f_val->cmp(target->value, val) == 0) \ + return &(_map_->buffer[pos % _map_->capacity][1]); \ +\ + pos++; \ + target = _map_->buffer[pos % _map_->capacity][1]; \ + } \ +\ + return NULL; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_add_entry_to_key)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \ + { \ + struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \ +\ + size_t hash = _map_->f_key->hash(entry->key); \ + size_t original_pos = hash % _map_->capacity; \ + size_t pos = original_pos; \ +\ + struct CMC_DEF_ENTRY(SNAME) **scan = &(_map_->buffer[hash % _map_->capacity][0]); \ +\ + if (*scan == NULL) \ + { \ + *scan = entry; \ +\ + entry->ref[0] = scan; \ +\ + return scan; \ + } \ + else \ + { \ + while (true) \ + { \ + pos++; \ + scan = &(_map_->buffer[pos % _map_->capacity][0]); \ +\ + if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \ + { \ + if (!to_return) \ + to_return = scan; \ +\ + *scan = entry; \ + entry->ref[0] = scan; \ + entry->dist[0] = pos - original_pos; \ +\ + return to_return; \ + } \ + else if ((*scan)->dist[0] < pos - original_pos) \ + { \ + if (!to_return) \ + to_return = scan; \ +\ + size_t tmp_dist = (*scan)->dist[0]; \ + entry->dist[0] = pos - original_pos; \ + original_pos = pos - tmp_dist; \ +\ + entry->ref[0] = scan; \ +\ + struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \ + *scan = entry; \ + entry = _tmp_; \ + } \ + } \ + } \ +\ + return NULL; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * \ + *CMC_(PFX, _impl_add_entry_to_val)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \ + { \ + struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \ +\ + size_t hash = _map_->f_val->hash(entry->value); \ + size_t original_pos = hash % _map_->capacity; \ + size_t pos = original_pos; \ +\ + struct CMC_DEF_ENTRY(SNAME) **scan = &(_map_->buffer[hash % _map_->capacity][1]); \ +\ + if (*scan == NULL) \ + { \ + *scan = entry; \ +\ + entry->ref[1] = scan; \ +\ + return scan; \ + } \ + else \ + { \ + while (true) \ + { \ + pos++; \ + scan = &(_map_->buffer[pos % _map_->capacity][1]); \ +\ + if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \ + { \ + if (!to_return) \ + to_return = scan; \ +\ + *scan = entry; \ + entry->ref[1] = scan; \ + entry->dist[1] = pos - original_pos; \ +\ + return to_return; \ + } \ + else if ((*scan)->dist[1] < pos - original_pos) \ + { \ + if (!to_return) \ + to_return = scan; \ +\ + size_t tmp_dist = (*scan)->dist[1]; \ + entry->dist[1] = pos - original_pos; \ + original_pos = pos - tmp_dist; \ +\ + entry->ref[1] = scan; \ +\ + struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \ + *scan = entry; \ + entry = _tmp_; \ + } \ + } \ + } \ +\ + return NULL; \ + } \ +\ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ + { \ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ +\ + if (cmc_hashtable_primes[count - 1] < required) \ + return required; \ +\ + size_t i = 0; \ + while (cmc_hashtable_primes[i] < required) \ + i++; \ +\ + return cmc_hashtable_primes[i]; \ + } \ +\ + static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_start)(struct SNAME * _map_) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + CMC_(PFX, _iter_init)(&iter, _map_); \ +\ + return iter; \ + } \ +\ + static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_end)(struct SNAME * _map_) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + CMC_(PFX, _iter_init)(&iter, _map_); \ + CMC_(PFX, _iter_to_end)(&iter); \ +\ + return iter; \ } #endif /* CMC_CMC_HASHBIDIMAP_H */ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index a122669..3ac5ae1 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -32,802 +32,776 @@ /** * Core HashMap implementation */ -#define CMC_CMC_HASHMAP_CORE(PARAMS) \ +#define CMC_CMC_HASHMAP_CORE(PARAMS) \ CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \ CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ +#define CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ +#define CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \ - \ - /* Hashmap Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of keys */ \ - size_t count; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Hashmap Entry */ \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry Key */ \ - K key; \ - \ - /* Entry Value */ \ - V value; \ - \ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ - \ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; \ - \ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(K); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(K); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(K); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(K); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(K); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(K); \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_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); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ - V * old_value); \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - bool CMC_(PFX, _full)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ - double CMC_(PFX, _load)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ +#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \ +\ + /* Hashmap Structure */ \ + struct SNAME \ + { \ + /* Array of Entries */ \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ +\ + /* Current array capacity */ \ + size_t capacity; \ +\ + /* Current amount of keys */ \ + size_t count; \ +\ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Key function table */ \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Hashmap Entry */ \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry Key */ \ + K key; \ +\ + /* Entry Value */ \ + V value; \ +\ + /* The distance of this node to its original position, used by */ \ + /* robin-hood hashing */ \ + size_t dist; \ +\ + /* The sate of this node (DELETED, EMPTY, FILLED) */ \ + enum cmc_entry_state state; \ + }; \ +\ + /* Key struct function table */ \ + struct CMC_DEF_FKEY(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(K); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(K); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(K); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(K); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(K); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(K); \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + bool CMC_(PFX, _full)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ + double CMC_(PFX, _load)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ - \ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, \ - NULL); \ - } \ - \ - struct SNAME *CMC_(PFX, _new_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) \ - { \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_key || !f_val) \ - return NULL; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ - \ - if (!_map_->buffer) \ - { \ - alloc->free(_map_); \ - return NULL; \ - } \ - \ - _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_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _map_) \ - { \ - if (_map_->f_key->free || _map_->f_val->free) \ - { \ - 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->free) \ - _map_->f_key->free(entry->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(entry->value); \ - } \ - } \ - } \ - \ - memset(_map_->buffer, 0, \ - sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \ - \ - _map_->count = 0; \ - _map_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _map_) \ - { \ - if (_map_->f_key->free || _map_->f_val->free) \ - { \ - 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->free) \ - _map_->f_key->free(entry->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(entry->value); \ - } \ - } \ - } \ - \ - _map_->alloc->free(_map_->buffer); \ - _map_->alloc->free(_map_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ - \ - _map_->callbacks = callbacks; \ - \ - _map_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ - { \ - if (CMC_(PFX, _full)(_map_)) \ - { \ - if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ - return false; \ - } \ - \ - if (CMC_(PFX, _impl_get_entry)(_map_, key) != NULL) \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - size_t original_pos = hash % _map_->capacity; \ - size_t pos = original_pos; \ - \ - struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \ - \ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->key = key; \ - target->value = value; \ - target->dist = 0; \ - target->state = CMC_ES_FILLED; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - target = &(_map_->buffer[pos % _map_->capacity]); \ - \ - if (target->state == CMC_ES_EMPTY || \ - target->state == CMC_ES_DELETED) \ - { \ - target->key = key; \ - target->value = value; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ - \ - break; \ - } \ - else if (target->dist < pos - original_pos) \ - { \ - K tmp_k = target->key; \ - V tmp_v = target->value; \ - size_t tmp_dist = target->dist; \ - \ - target->key = key; \ - target->value = value; \ - target->dist = pos - original_pos; \ - \ - key = tmp_k; \ - value = tmp_v; \ - original_pos = pos - tmp_dist; \ - } \ - } \ - } \ - \ - _map_->count++; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ - V * old_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - if (old_value) \ - *old_value = entry->value; \ - \ - entry->value = new_value; \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *result = \ - CMC_(PFX, _impl_get_entry)(_map_, key); \ - \ - if (result == NULL) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - if (out_value) \ - *out_value = result->value; \ - \ - result->key = (K){ 0 }; \ - result->value = (V){ 0 }; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ - \ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - K max_key; \ - V max_val; \ - size_t first = 0; \ - \ - for (; first < _map_->capacity; first++) \ - { \ - if (_map_->buffer[first].state == CMC_ES_FILLED) \ - { \ - max_key = _map_->buffer[first].key; \ - max_val = _map_->buffer[first].value; \ - break; \ - } \ - } \ - \ - for (size_t i = first + 1; i < _map_->capacity; i++) \ - { \ - if (_map_->buffer[i].state == CMC_ES_FILLED) \ - { \ - if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ - { \ - max_key = _map_->buffer[first].key; \ - max_val = _map_->buffer[first].value; \ - } \ - } \ - } \ - \ - if (key) \ - *key = max_key; \ - if (value) \ - *value = max_val; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - K min_key; \ - V min_val; \ - size_t first = 0; \ - \ - for (; first < _map_->capacity; first++) \ - { \ - if (_map_->buffer[first].state == CMC_ES_FILLED) \ - { \ - min_key = _map_->buffer[first].key; \ - min_val = _map_->buffer[first].value; \ - break; \ - } \ - } \ - \ - for (size_t i = first + 1; i < _map_->capacity; i++) \ - { \ - if (_map_->buffer[i].state == CMC_ES_FILLED) \ - { \ - if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) > 0) \ - { \ - min_key = _map_->buffer[first].key; \ - min_val = _map_->buffer[first].value; \ - } \ - } \ - } \ - \ - if (key) \ - *key = min_key; \ - if (value) \ - *value = min_val; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return entry->value; \ - } \ - \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return NULL; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return &(entry->value); \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ - { \ - _map_->flag = CMC_FLAG_OK; \ - \ - bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _map_) \ - { \ - return _map_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _map_) \ - { \ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _map_) \ - { \ - return _map_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ - { \ - return _map_->capacity; \ - } \ - \ - double CMC_(PFX, _load)(struct SNAME * _map_) \ - { \ - return _map_->load; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _map_) \ - { \ - return _map_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ - { \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->capacity == capacity) \ - goto success; \ - \ - if (_map_->capacity > capacity / _map_->load) \ - goto success; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _map_->load) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ - \ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _map_->count / _map_->load) \ - { \ - _map_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - /* No callbacks since _new_map_ is just a temporary hashtable */ \ - struct SNAME *_new_map_ = \ - CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ - \ - if (!_new_map_) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - if (_map_->buffer[i].state == CMC_ES_FILLED) \ - { \ - K key = _map_->buffer[i].key; \ - V value = _map_->buffer[i].value; \ - \ - /* TODO check this for possible errors */ \ - CMC_(PFX, _insert)(_new_map_, key, value); \ - } \ - } \ - \ - /* Unlikely */ \ - if (_map_->count != _new_map_->count) \ - { \ - CMC_(PFX, _free)(_new_map_); \ - \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *tmp_b = _map_->buffer; \ - _map_->buffer = _new_map_->buffer; \ - _new_map_->buffer = tmp_b; \ - \ - size_t tmp_c = _map_->capacity; \ - _map_->capacity = _new_map_->capacity; \ - _new_map_->capacity = tmp_c; \ - \ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ - _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ - \ - CMC_(PFX, _free)(_new_map_); \ - \ - success: \ - \ - if (_map_->callbacks && _map_->callbacks->resize) \ - _map_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _map_->capacity * _map_->load, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, _map_->callbacks); \ - \ - if (!result) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_map_->f_key->cpy || _map_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = &(_map_->buffer[i]); \ - \ - if (scan->state != CMC_ES_EMPTY) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *target = \ - &(result->buffer[i]); \ - \ - if (scan->state == CMC_ES_DELETED) \ - target->state = CMC_ES_DELETED; \ - else \ - { \ - target->state = scan->state; \ - target->dist = scan->dist; \ - \ - if (_map_->f_key->cpy) \ - target->key = _map_->f_key->cpy(scan->key); \ - else \ - target->key = scan->key; \ - \ - if (_map_->f_val->cpy) \ - target->value = _map_->f_val->cpy(scan->value); \ - else \ - target->value = scan->value; \ - } \ - } \ - } \ - } \ - else \ - memcpy(result->buffer, _map_->buffer, \ - sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \ - \ - result->count = _map_->count; \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ - { \ - _map1_->flag = CMC_FLAG_OK; \ - _map2_->flag = CMC_FLAG_OK; \ - \ - if (_map1_->count != _map2_->count) \ - return false; \ - \ - /* Optimize loop using the smallest hashtable */ \ - struct SNAME *_map_a_; \ - struct SNAME *_map_b_; \ - \ - _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \ - _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \ - \ - for (size_t i = 0; i < _map_a_->capacity; i++) \ - { \ - if (_map_a_->buffer[i].state == CMC_ES_FILLED) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_map_a_->buffer[i]); \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry_b = \ - CMC_(PFX, _impl_get_entry)(_map_b_, entry_a->key); \ - \ - if (!entry_b) \ - return false; \ - \ - if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) \ - return false; \ - } \ - } \ - \ - return true; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - size_t pos = hash % _map_->capacity; \ - \ - struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \ - \ - while (target->state == CMC_ES_FILLED || \ - target->state == CMC_ES_DELETED) \ - { \ - if (_map_->f_key->cmp(target->key, key) == 0) \ - return target; \ - \ - pos++; \ - target = &(_map_->buffer[pos % _map_->capacity]); \ - } \ - \ - return NULL; \ - } \ - \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = \ - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ - \ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ - \ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ - \ - return cmc_hashtable_primes[i]; \ +#define CMC_CMC_HASHMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ +\ + /* Implementation Detail Functions */ \ + static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity == 0 || load <= 0 || load >= 1) \ + return NULL; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ +\ + if (!f_key || !f_val) \ + return NULL; \ +\ + size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_map_) \ + return NULL; \ +\ + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ +\ + if (!_map_->buffer) \ + { \ + alloc->free(_map_); \ + return NULL; \ + } \ +\ + _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; \ + CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ +\ + return _map_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _map_) \ + { \ + if (_map_->f_key->free || _map_->f_val->free) \ + { \ + 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->free) \ + _map_->f_key->free(entry->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(entry->value); \ + } \ + } \ + } \ +\ + memset(_map_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \ +\ + _map_->count = 0; \ + _map_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _map_) \ + { \ + if (_map_->f_key->free || _map_->f_val->free) \ + { \ + 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->free) \ + _map_->f_key->free(entry->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(entry->value); \ + } \ + } \ + } \ +\ + _map_->alloc->free(_map_->buffer); \ + _map_->alloc->free(_map_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _map_->alloc = &cmc_alloc_node_default; \ + else \ + _map_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ +\ + _map_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ + { \ + if (CMC_(PFX, _full)(_map_)) \ + { \ + if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ + return false; \ + } \ +\ + if (CMC_(PFX, _impl_get_entry)(_map_, key) != NULL) \ + { \ + _map_->flag = CMC_FLAG_DUPLICATE; \ + return false; \ + } \ +\ + size_t hash = _map_->f_key->hash(key); \ + size_t original_pos = hash % _map_->capacity; \ + size_t pos = original_pos; \ +\ + struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \ +\ + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ + { \ + target->key = key; \ + target->value = value; \ + target->dist = 0; \ + target->state = CMC_ES_FILLED; \ + } \ + else \ + { \ + while (true) \ + { \ + pos++; \ + target = &(_map_->buffer[pos % _map_->capacity]); \ +\ + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ + { \ + target->key = key; \ + target->value = value; \ + target->dist = pos - original_pos; \ + target->state = CMC_ES_FILLED; \ +\ + break; \ + } \ + else if (target->dist < pos - original_pos) \ + { \ + K tmp_k = target->key; \ + V tmp_v = target->value; \ + size_t tmp_dist = target->dist; \ +\ + target->key = key; \ + target->value = value; \ + target->dist = pos - original_pos; \ +\ + key = tmp_k; \ + value = tmp_v; \ + original_pos = pos - tmp_dist; \ + } \ + } \ + } \ +\ + _map_->count++; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->create) \ + _map_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ +\ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + if (old_value) \ + *old_value = entry->value; \ +\ + entry->value = new_value; \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_map_, key); \ +\ + if (result == NULL) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + if (out_value) \ + *out_value = result->value; \ +\ + result->key = (K){ 0 }; \ + result->value = (V){ 0 }; \ + result->dist = 0; \ + result->state = CMC_ES_DELETED; \ +\ + _map_->count--; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + K max_key; \ + V max_val; \ + size_t first = 0; \ +\ + for (; first < _map_->capacity; first++) \ + { \ + if (_map_->buffer[first].state == CMC_ES_FILLED) \ + { \ + max_key = _map_->buffer[first].key; \ + max_val = _map_->buffer[first].value; \ + break; \ + } \ + } \ +\ + for (size_t i = first + 1; i < _map_->capacity; i++) \ + { \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ + { \ + max_key = _map_->buffer[first].key; \ + max_val = _map_->buffer[first].value; \ + } \ + } \ + } \ +\ + if (key) \ + *key = max_key; \ + if (value) \ + *value = max_val; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + K min_key; \ + V min_val; \ + size_t first = 0; \ +\ + for (; first < _map_->capacity; first++) \ + { \ + if (_map_->buffer[first].state == CMC_ES_FILLED) \ + { \ + min_key = _map_->buffer[first].key; \ + min_val = _map_->buffer[first].value; \ + break; \ + } \ + } \ +\ + for (size_t i = first + 1; i < _map_->capacity; i++) \ + { \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) > 0) \ + { \ + min_key = _map_->buffer[first].key; \ + min_val = _map_->buffer[first].value; \ + } \ + } \ + } \ +\ + if (key) \ + *key = min_key; \ + if (value) \ + *value = min_val; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ +\ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return (V){ 0 }; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return entry->value; \ + } \ +\ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ +\ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return NULL; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return &(entry->value); \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ + { \ + _map_->flag = CMC_FLAG_OK; \ +\ + bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _map_) \ + { \ + return _map_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _map_) \ + { \ + return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _map_) \ + { \ + return _map_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ + { \ + return _map_->capacity; \ + } \ +\ + double CMC_(PFX, _load)(struct SNAME * _map_) \ + { \ + return _map_->load; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _map_) \ + { \ + return _map_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ + { \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->capacity == capacity) \ + goto success; \ +\ + if (_map_->capacity > capacity / _map_->load) \ + goto success; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * _map_->load) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + /* Calculate required capacity based on the prime numbers */ \ + size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ +\ + /* Not possible to shrink with current available prime numbers */ \ + if (theoretical_size < _map_->count / _map_->load) \ + { \ + _map_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + /* No callbacks since _new_map_ is just a temporary hashtable */ \ + struct SNAME *_new_map_ = \ + CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ +\ + if (!_new_map_) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + K key = _map_->buffer[i].key; \ + V value = _map_->buffer[i].value; \ +\ + /* TODO check this for possible errors */ \ + CMC_(PFX, _insert)(_new_map_, key, value); \ + } \ + } \ +\ + /* Unlikely */ \ + if (_map_->count != _new_map_->count) \ + { \ + CMC_(PFX, _free)(_new_map_); \ +\ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *tmp_b = _map_->buffer; \ + _map_->buffer = _new_map_->buffer; \ + _new_map_->buffer = tmp_b; \ +\ + size_t tmp_c = _map_->capacity; \ + _map_->capacity = _new_map_->capacity; \ + _new_map_->capacity = tmp_c; \ +\ + /* Prevent the map from freeing the data */ \ + _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ + _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ +\ + CMC_(PFX, _free)(_new_map_); \ +\ + success: \ +\ + if (_map_->callbacks && _map_->callbacks->resize) \ + _map_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, NULL); \ +\ + if (!result) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ +\ + if (_map_->f_key->cpy || _map_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = &(_map_->buffer[i]); \ +\ + if (scan->state != CMC_ES_EMPTY) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \ +\ + if (scan->state == CMC_ES_DELETED) \ + target->state = CMC_ES_DELETED; \ + else \ + { \ + target->state = scan->state; \ + target->dist = scan->dist; \ +\ + if (_map_->f_key->cpy) \ + target->key = _map_->f_key->cpy(scan->key); \ + else \ + target->key = scan->key; \ +\ + if (_map_->f_val->cpy) \ + target->value = _map_->f_val->cpy(scan->value); \ + else \ + target->value = scan->value; \ + } \ + } \ + } \ + } \ + else \ + memcpy(result->buffer, _map_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \ +\ + result->count = _map_->count; \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ + { \ + _map1_->flag = CMC_FLAG_OK; \ + _map2_->flag = CMC_FLAG_OK; \ +\ + if (_map1_->count != _map2_->count) \ + return false; \ +\ + /* Optimize loop using the smallest hashtable */ \ + struct SNAME *_map_a_; \ + struct SNAME *_map_b_; \ +\ + _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \ + _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \ +\ + for (size_t i = 0; i < _map_a_->capacity; i++) \ + { \ + if (_map_a_->buffer[i].state == CMC_ES_FILLED) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_map_a_->buffer[i]); \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry_b = CMC_(PFX, _impl_get_entry)(_map_b_, entry_a->key); \ +\ + if (!entry_b) \ + return false; \ +\ + if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) \ + return false; \ + } \ + } \ +\ + return true; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ + { \ + size_t hash = _map_->f_key->hash(key); \ + size_t pos = hash % _map_->capacity; \ +\ + struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \ +\ + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \ + { \ + if (_map_->f_key->cmp(target->key, key) == 0) \ + return target; \ +\ + pos++; \ + target = &(_map_->buffer[pos % _map_->capacity]); \ + } \ +\ + return NULL; \ + } \ +\ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ + { \ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ +\ + if (cmc_hashtable_primes[count - 1] < required) \ + return required; \ +\ + size_t i = 0; \ + while (cmc_hashtable_primes[i] < required) \ + i++; \ +\ + return cmc_hashtable_primes[i]; \ } #endif /* CMC_CMC_HASHMAP_H */ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index f46d1a5..38dea54 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -57,1063 +57,987 @@ /** * Core HashMultiMap implementation */ -#define CMC_CMC_HASHMULTIMAP_CORE(PARAMS) \ +#define CMC_CMC_HASHMULTIMAP_CORE(PARAMS) \ CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \ CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ - \ - /* HashMultimap Structure */ \ - struct SNAME \ - { \ - /* Array of linked list to entries */ \ - struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of keys */ \ - size_t count; \ - \ - /* Load factor in range (0.0, infinity) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* HashMultimap Entry */ \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry Key */ \ - K key; \ - \ - /* Entry Value */ \ - V value; \ - \ - /* Next entry on the linked list */ \ - struct CMC_DEF_ENTRY(SNAME) * next; \ - \ - /* Previous entry on the linked list */ \ - struct CMC_DEF_ENTRY(SNAME) * prev; \ - }; \ - \ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(K); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(K); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(K); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(K); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(K); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(K); \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_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); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ - V * old_value); \ - size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, \ - V * *old_values); \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ - size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, \ - V * *out_values); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - bool CMC_(PFX, _full)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ - double CMC_(PFX, _load)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ +#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ +\ + /* HashMultimap Structure */ \ + struct SNAME \ + { \ + /* Array of linked list to entries */ \ + struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ +\ + /* Current array capacity */ \ + size_t capacity; \ +\ + /* Current amount of keys */ \ + size_t count; \ +\ + /* Load factor in range (0.0, infinity) */ \ + double load; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Key function table */ \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* HashMultimap Entry */ \ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry Key */ \ + K key; \ +\ + /* Entry Value */ \ + V value; \ +\ + /* Next entry on the linked list */ \ + struct CMC_DEF_ENTRY(SNAME) * next; \ +\ + /* Previous entry on the linked list */ \ + struct CMC_DEF_ENTRY(SNAME) * prev; \ + }; \ +\ + /* Key struct function table */ \ + struct CMC_DEF_FKEY(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(K); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(K); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(K); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(K); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(K); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(K); \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \ + size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, V * *old_values); \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ + size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, V * *out_values); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + bool CMC_(PFX, _full)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ + double CMC_(PFX, _load)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ - \ - /* Implementation Detail Functions */ \ - struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \ - struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \ - size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key); \ - size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity == 0 || load <= 0) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_key || !f_val) \ - return NULL; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->buffer = alloc->calloc( \ - real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ - \ - if (!_map_->buffer) \ - { \ - alloc->free(_map_); \ - return NULL; \ - } \ - \ - _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 = NULL; \ - \ - return _map_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_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) \ - { \ - if (capacity == 0 || load <= 0) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_key || !f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->buffer = alloc->calloc( \ - real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ - \ - if (!_map_->buffer) \ - { \ - alloc->free(_map_); \ - return NULL; \ - } \ - \ - _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_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _map_) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ - \ - while (scan != NULL) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *next = scan->next; \ - \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ - \ - _map_->alloc->free(scan); \ - \ - scan = next; \ - } \ - } \ - \ - memset(_map_->buffer, 0, \ - sizeof(struct CMC_DEF_ENTRY(SNAME) *[2]) * _map_->capacity); \ - \ - _map_->count = 0; \ - _map_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _map_) \ - { \ - size_t index = 0; \ - \ - while (index < _map_->capacity) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[index][0]; \ - \ - if (scan != NULL) \ - { \ - if (scan->next == NULL && scan->prev == NULL) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ - \ - _map_->alloc->free(scan); \ - } \ - else \ - { \ - while (scan != NULL) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *tmp = scan; \ - \ - scan = scan->next; \ - \ - if (_map_->f_key->free) \ - _map_->f_key->free(tmp->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(tmp->value); \ - \ - _map_->alloc->free(tmp); \ - } \ - } \ - } \ - \ - index++; \ - } \ - \ - _map_->alloc->free(_map_->buffer); \ - _map_->alloc->free(_map_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ - \ - _map_->callbacks = callbacks; \ - \ - _map_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ - { \ - if (CMC_(PFX, _full)(_map_)) \ - { \ - if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ - return false; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - size_t pos = hash % _map_->capacity; \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_new_entry)(_map_, key, value); \ - \ - if (_map_->buffer[pos][0] == NULL) \ - { \ - _map_->buffer[pos][0] = entry; \ - _map_->buffer[pos][1] = entry; \ - } \ - else \ - { \ - entry->prev = _map_->buffer[pos][1]; \ - \ - _map_->buffer[pos][1]->next = entry; \ - _map_->buffer[pos][1] = entry; \ - } \ - \ - _map_->count++; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ - V * old_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - if (old_value) \ - *old_value = entry->value; \ - \ - entry->value = new_value; \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return true; \ - } \ - \ - size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, \ - V * *old_values) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return 0; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - _map_->buffer[hash % _map_->capacity][0]; \ - \ - if (entry == NULL) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ - \ - if (old_values) \ - { \ - size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \ - \ - if (total == 0) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ - \ - *old_values = _map_->alloc->malloc(sizeof(V) * total); \ - \ - if (!(*old_values)) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return 0; \ - } \ - } \ - \ - size_t index = 0; \ - \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (old_values) \ - (*old_values)[index] = entry->value; \ - \ - index++; \ - entry->value = new_value; \ - } \ - \ - entry = entry->next; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return index; \ - } \ - \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct CMC_DEF_ENTRY(SNAME) **head = \ - &(_map_->buffer[hash % _map_->capacity][0]); \ - struct CMC_DEF_ENTRY(SNAME) **tail = \ - &(_map_->buffer[hash % _map_->capacity][1]); \ - \ - if (*head == NULL) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = *head; \ - \ - if (entry->next == NULL && entry->prev == NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - *head = NULL; \ - *tail = NULL; \ - \ - if (out_value) \ - *out_value = entry->value; \ - } \ - else \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - } \ - else \ - { \ - bool found = false; \ - \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (*head == entry) \ - *head = entry->next; \ - if (*tail == entry) \ - *tail = entry->prev; \ - \ - if (entry->prev != NULL) \ - entry->prev->next = entry->next; \ - if (entry->next != NULL) \ - entry->next->prev = entry->prev; \ - \ - if (out_value) \ - *out_value = entry->value; \ - \ - found = true; \ - \ - break; \ - } \ - else \ - entry = entry->next; \ - } \ - \ - if (!found) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - } \ - \ - _map_->alloc->free(entry); \ - \ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, \ - V * *out_values) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct CMC_DEF_ENTRY(SNAME) **head = \ - &(_map_->buffer[hash % _map_->capacity][0]); \ - struct CMC_DEF_ENTRY(SNAME) **tail = \ - &(_map_->buffer[hash % _map_->capacity][1]); \ - \ - if (*head == NULL) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ - \ - if (out_values) \ - { \ - size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \ - \ - if (total == 0) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ - \ - *out_values = _map_->alloc->malloc(sizeof(V) * total); \ - \ - if (!(*out_values)) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return 0; \ - } \ - } \ - \ - size_t index = 0; \ - struct CMC_DEF_ENTRY(SNAME) *entry = *head; \ - \ - if (entry->next == NULL) \ - { \ - *head = NULL; \ - *tail = NULL; \ - \ - if (out_values) \ - (*out_values)[index] = entry->value; \ - \ - index++; \ - _map_->alloc->free(entry); \ - } \ - else \ - { \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (*head == entry) \ - *head = entry->next; \ - if (*tail == entry) \ - *tail = entry->prev; \ - \ - struct CMC_DEF_ENTRY(SNAME) *next = entry->next; \ - \ - if (entry->prev != NULL) \ - entry->prev->next = entry->next; \ - if (entry->next != NULL) \ - entry->next->prev = entry->prev; \ - \ - if (out_values) \ - (*out_values)[index] = entry->value; \ - \ - index++; \ - _map_->alloc->free(entry); \ - \ - entry = next; \ - } \ - else \ - entry = entry->next; \ - } \ - } \ - \ - _map_->count -= index; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return index; \ - } \ - \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - K max_key; \ - V max_val; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ - \ - /* TODO Turn this into a normal loop */ \ +#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ +\ + /* Implementation Detail Functions */ \ + struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \ + struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \ + size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key); \ + size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ + struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity == 0 || load <= 0) \ + return NULL; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ +\ + if (!f_key || !f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ +\ + struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_map_) \ + return NULL; \ +\ + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ +\ + if (!_map_->buffer) \ + { \ + alloc->free(_map_); \ + return NULL; \ + } \ +\ + _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; \ + CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ +\ + return _map_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _map_) \ + { \ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ +\ + while (scan != NULL) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *next = scan->next; \ +\ + if (_map_->f_key->free) \ + _map_->f_key->free(scan->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(scan->value); \ +\ + _map_->alloc->free(scan); \ +\ + scan = next; \ + } \ + } \ +\ + memset(_map_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2]) * _map_->capacity); \ +\ + _map_->count = 0; \ + _map_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _map_) \ + { \ + size_t index = 0; \ +\ + while (index < _map_->capacity) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[index][0]; \ +\ + if (scan != NULL) \ + { \ + if (scan->next == NULL && scan->prev == NULL) \ + { \ + if (_map_->f_key->free) \ + _map_->f_key->free(scan->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(scan->value); \ +\ + _map_->alloc->free(scan); \ + } \ + else \ + { \ + while (scan != NULL) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *tmp = scan; \ +\ + scan = scan->next; \ +\ + if (_map_->f_key->free) \ + _map_->f_key->free(tmp->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(tmp->value); \ +\ + _map_->alloc->free(tmp); \ + } \ + } \ + } \ +\ + index++; \ + } \ +\ + _map_->alloc->free(_map_->buffer); \ + _map_->alloc->free(_map_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _map_->alloc = &cmc_alloc_node_default; \ + else \ + _map_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ +\ + _map_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ + { \ + if (CMC_(PFX, _full)(_map_)) \ + { \ + if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ + return false; \ + } \ +\ + size_t hash = _map_->f_key->hash(key); \ + size_t pos = hash % _map_->capacity; \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(_map_, key, value); \ +\ + if (_map_->buffer[pos][0] == NULL) \ + { \ + _map_->buffer[pos][0] = entry; \ + _map_->buffer[pos][1] = entry; \ + } \ + else \ + { \ + entry->prev = _map_->buffer[pos][1]; \ +\ + _map_->buffer[pos][1]->next = entry; \ + _map_->buffer[pos][1] = entry; \ + } \ +\ + _map_->count++; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->create) \ + _map_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ +\ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + if (old_value) \ + *old_value = entry->value; \ +\ + entry->value = new_value; \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ +\ + return true; \ + } \ +\ + size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, V * *old_values) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return 0; \ + } \ +\ + size_t hash = _map_->f_key->hash(key); \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \ +\ + if (entry == NULL) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ +\ + if (old_values) \ + { \ + size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \ +\ + if (total == 0) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ +\ + *old_values = _map_->alloc->malloc(sizeof(V) * total); \ +\ + if (!(*old_values)) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return 0; \ + } \ + } \ +\ + size_t index = 0; \ +\ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + { \ + if (old_values) \ + (*old_values)[index] = entry->value; \ +\ + index++; \ + entry->value = new_value; \ + } \ +\ + entry = entry->next; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ +\ + return index; \ + } \ +\ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + size_t hash = _map_->f_key->hash(key); \ +\ + struct CMC_DEF_ENTRY(SNAME) **head = &(_map_->buffer[hash % _map_->capacity][0]); \ + struct CMC_DEF_ENTRY(SNAME) **tail = &(_map_->buffer[hash % _map_->capacity][1]); \ +\ + if (*head == NULL) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = *head; \ +\ + if (entry->next == NULL && entry->prev == NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + { \ + *head = NULL; \ + *tail = NULL; \ +\ + if (out_value) \ + *out_value = entry->value; \ + } \ + else \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ + } \ + else \ + { \ + bool found = false; \ +\ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + { \ + if (*head == entry) \ + *head = entry->next; \ + if (*tail == entry) \ + *tail = entry->prev; \ +\ + if (entry->prev != NULL) \ + entry->prev->next = entry->next; \ + if (entry->next != NULL) \ + entry->next->prev = entry->prev; \ +\ + if (out_value) \ + *out_value = entry->value; \ +\ + found = true; \ +\ + break; \ + } \ + else \ + entry = entry->next; \ + } \ +\ + if (!found) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ + } \ +\ + _map_->alloc->free(entry); \ +\ + _map_->count--; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, V * *out_values) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + size_t hash = _map_->f_key->hash(key); \ +\ + struct CMC_DEF_ENTRY(SNAME) **head = &(_map_->buffer[hash % _map_->capacity][0]); \ + struct CMC_DEF_ENTRY(SNAME) **tail = &(_map_->buffer[hash % _map_->capacity][1]); \ +\ + if (*head == NULL) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ +\ + if (out_values) \ + { \ + size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \ +\ + if (total == 0) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ +\ + *out_values = _map_->alloc->malloc(sizeof(V) * total); \ +\ + if (!(*out_values)) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return 0; \ + } \ + } \ +\ + size_t index = 0; \ + struct CMC_DEF_ENTRY(SNAME) *entry = *head; \ +\ + if (entry->next == NULL) \ + { \ + *head = NULL; \ + *tail = NULL; \ +\ + if (out_values) \ + (*out_values)[index] = entry->value; \ +\ + index++; \ + _map_->alloc->free(entry); \ + } \ + else \ + { \ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + { \ + if (*head == entry) \ + *head = entry->next; \ + if (*tail == entry) \ + *tail = entry->prev; \ +\ + struct CMC_DEF_ENTRY(SNAME) *next = entry->next; \ +\ + if (entry->prev != NULL) \ + entry->prev->next = entry->next; \ + if (entry->next != NULL) \ + entry->next->prev = entry->prev; \ +\ + if (out_values) \ + (*out_values)[index] = entry->value; \ +\ + index++; \ + _map_->alloc->free(entry); \ +\ + entry = next; \ + } \ + else \ + entry = entry->next; \ + } \ + } \ +\ + _map_->count -= index; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ +\ + return index; \ + } \ +\ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + K max_key; \ + V max_val; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ +\ + /* TODO Turn this into a normal loop */ \ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - K result_key = CMC_(PFX, _iter_key)(&iter); \ - V result_value = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ - \ - if (index == 0) \ - { \ - max_key = result_key; \ - max_val = result_value; \ - } \ - else if (_map_->f_key->cmp(result_key, max_key) > 0) \ - { \ - max_key = result_key; \ - max_val = result_value; \ - } \ - } \ - \ - if (key) \ - *key = max_key; \ - if (value) \ - *value = max_val; \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - K min_key; \ - V min_val; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ - \ - /* TODO Turn this into a normal loop */ \ + { \ + K result_key = CMC_(PFX, _iter_key)(&iter); \ + V result_value = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ +\ + if (index == 0) \ + { \ + max_key = result_key; \ + max_val = result_value; \ + } \ + else if (_map_->f_key->cmp(result_key, max_key) > 0) \ + { \ + max_key = result_key; \ + max_val = result_value; \ + } \ + } \ +\ + if (key) \ + *key = max_key; \ + if (value) \ + *value = max_val; \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + K min_key; \ + V min_val; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ +\ + /* TODO Turn this into a normal loop */ \ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - K result_key = CMC_(PFX, _iter_key)(&iter); \ - V result_value = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ - \ - if (index == 0) \ - { \ - min_key = result_key; \ - min_val = result_value; \ - } \ - else if (_map_->f_key->cmp(result_key, min_key) < 0) \ - { \ - min_key = result_key; \ - min_val = result_value; \ - } \ - } \ - \ - if (key) \ - *key = min_key; \ - if (value) \ - *value = min_val; \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return entry->value; \ - } \ - \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_map_, key); \ - \ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return NULL; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return &(entry->value); \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ - { \ - _map_->flag = CMC_FLAG_OK; \ - \ - bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _map_) \ - { \ - return _map_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _map_) \ - { \ + { \ + K result_key = CMC_(PFX, _iter_key)(&iter); \ + V result_value = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ +\ + if (index == 0) \ + { \ + min_key = result_key; \ + min_val = result_value; \ + } \ + else if (_map_->f_key->cmp(result_key, min_key) < 0) \ + { \ + min_key = result_key; \ + min_val = result_value; \ + } \ + } \ +\ + if (key) \ + *key = min_key; \ + if (value) \ + *value = min_val; \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ +\ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return (V){ 0 }; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return entry->value; \ + } \ +\ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ +\ + if (!entry) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return NULL; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return &(entry->value); \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ + { \ + _map_->flag = CMC_FLAG_OK; \ +\ + bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _map_) \ + { \ + return _map_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _map_) \ + { \ return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _map_) \ - { \ - return _map_->count; \ - } \ - \ - size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key) \ - { \ - return CMC_(PFX, _impl_key_count)(_map_, key); \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ - { \ - return _map_->capacity; \ - } \ - \ - double CMC_(PFX, _load)(struct SNAME * _map_) \ - { \ - return _map_->load; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _map_) \ - { \ - return _map_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ - { \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->capacity == capacity) \ - goto success; \ - \ - if (_map_->capacity > capacity / _map_->load) \ - goto success; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _map_->load) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ - \ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _map_->count / _map_->load) \ - { \ - _map_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - /* No callbacks since _new_map_ is just a temporary hashtable */ \ - struct SNAME *_new_map_ = \ - CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ - \ - if (!_new_map_) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ - \ - /* TODO Turn this into a normal loop */ \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _map_) \ + { \ + return _map_->count; \ + } \ +\ + size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key) \ + { \ + return CMC_(PFX, _impl_key_count)(_map_, key); \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ + { \ + return _map_->capacity; \ + } \ +\ + double CMC_(PFX, _load)(struct SNAME * _map_) \ + { \ + return _map_->load; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _map_) \ + { \ + return _map_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ + { \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->capacity == capacity) \ + goto success; \ +\ + if (_map_->capacity > capacity / _map_->load) \ + goto success; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * _map_->load) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + /* Calculate required capacity based on the prime numbers */ \ + size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ +\ + /* Not possible to shrink with current available prime numbers */ \ + if (theoretical_size < _map_->count / _map_->load) \ + { \ + _map_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + /* No callbacks since _new_map_ is just a temporary hashtable */ \ + struct SNAME *_new_map_ = \ + CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ +\ + if (!_new_map_) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ +\ + /* TODO Turn this into a normal loop */ \ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - /* TODO check for errors */ \ - CMC_(PFX, _insert)(_new_map_, key, value); \ - } \ - \ - if (_map_->count != _new_map_->count) \ - { \ - CMC_(PFX, _free)(_new_map_); \ - \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) * (*tmp_b)[2] = _map_->buffer; \ - _map_->buffer = _new_map_->buffer; \ - _new_map_->buffer = tmp_b; \ - \ - size_t tmp_c = _map_->capacity; \ - _map_->capacity = _new_map_->capacity; \ - _new_map_->capacity = tmp_c; \ - \ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ - _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ - \ - CMC_(PFX, _free)(_new_map_); \ - \ - success: \ - \ - if (_map_->callbacks && _map_->callbacks->resize) \ - _map_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ - { \ - /* Callback will be added later */ \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _map_->capacity * _map_->load, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ - \ - if (!result) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ - \ - if (!CMC_(PFX, _empty)(_map_)) \ - { \ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); \ - CMC_(PFX, _iter_next)(&iter)) \ - { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (_map_->f_key->cpy) \ - key = _map_->f_key->cpy(key); \ - if (_map_->f_val->cpy) \ - value = _map_->f_val->cpy(value); \ - \ - /* TODO check for errors */ \ - CMC_(PFX, _insert)(result, key, value); \ - } \ - } \ - \ - result->callbacks = _map_->callbacks; \ - _map_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ - { \ - _map1_->flag = CMC_FLAG_OK; \ - _map2_->flag = CMC_FLAG_OK; \ - \ - if (_map1_->count != _map2_->count) \ - return false; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ - \ - /* TODO Turn this into a normal loop */ \ + { \ + K key = CMC_(PFX, _iter_key)(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + /* TODO check for errors */ \ + CMC_(PFX, _insert)(_new_map_, key, value); \ + } \ +\ + if (_map_->count != _new_map_->count) \ + { \ + CMC_(PFX, _free)(_new_map_); \ +\ + _map_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) * (*tmp_b)[2] = _map_->buffer; \ + _map_->buffer = _new_map_->buffer; \ + _new_map_->buffer = tmp_b; \ +\ + size_t tmp_c = _map_->capacity; \ + _map_->capacity = _new_map_->capacity; \ + _new_map_->capacity = tmp_c; \ +\ + /* Prevent the map from freeing the data */ \ + _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ + _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ +\ + CMC_(PFX, _free)(_new_map_); \ +\ + success: \ +\ + if (_map_->callbacks && _map_->callbacks->resize) \ + _map_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ + { \ + /* Callback will be added later */ \ + struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \ + _map_->f_val, _map_->alloc, NULL); \ +\ + if (!result) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ +\ + if (!CMC_(PFX, _empty)(_map_)) \ + { \ + /* TODO Turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K key = CMC_(PFX, _iter_key)(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (_map_->f_key->cpy) \ + key = _map_->f_key->cpy(key); \ + if (_map_->f_val->cpy) \ + value = _map_->f_val->cpy(value); \ +\ + /* TODO check for errors */ \ + CMC_(PFX, _insert)(result, key, value); \ + } \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ + _map_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ + { \ + _map1_->flag = CMC_FLAG_OK; \ + _map2_->flag = CMC_FLAG_OK; \ +\ + if (_map1_->count != _map2_->count) \ + return false; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ +\ + /* TODO Turn this into a normal loop */ \ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - \ - if (CMC_(PFX, _impl_key_count)(_map1_, key) != \ - CMC_(PFX, _impl_key_count)(_map2_, key)) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \ - \ - if (!entry) \ - return NULL; \ - \ - entry->key = key; \ - entry->value = value; \ - entry->next = NULL; \ - entry->prev = NULL; \ - \ - return entry; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - _map_->buffer[hash % _map_->capacity][0]; \ - \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - return entry; \ - \ - entry = entry->next; \ - } \ - \ - return NULL; \ - } \ - \ - size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - _map_->buffer[hash % _map_->capacity][0]; \ - \ - size_t total_count = 0; \ - \ - if (!entry) \ - return total_count; \ - \ - while (entry != NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - total_count++; \ - \ - entry = entry->next; \ - } \ - \ - return total_count; \ - } \ - \ - size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = \ - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ - \ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ - \ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ - \ - return cmc_hashtable_primes[i]; \ + { \ + K key = CMC_(PFX, _iter_key)(&iter); \ +\ + if (CMC_(PFX, _impl_key_count)(_map1_, key) != CMC_(PFX, _impl_key_count)(_map2_, key)) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \ +\ + if (!entry) \ + return NULL; \ +\ + entry->key = key; \ + entry->value = value; \ + entry->next = NULL; \ + entry->prev = NULL; \ +\ + return entry; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ + { \ + size_t hash = _map_->f_key->hash(key); \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \ +\ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + return entry; \ +\ + entry = entry->next; \ + } \ +\ + return NULL; \ + } \ +\ + size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key) \ + { \ + size_t hash = _map_->f_key->hash(key); \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \ +\ + size_t total_count = 0; \ +\ + if (!entry) \ + return total_count; \ +\ + while (entry != NULL) \ + { \ + if (_map_->f_key->cmp(entry->key, key) == 0) \ + total_count++; \ +\ + entry = entry->next; \ + } \ +\ + return total_count; \ + } \ +\ + size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ + { \ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ +\ + if (cmc_hashtable_primes[count - 1] < required) \ + return required; \ +\ + size_t i = 0; \ + while (cmc_hashtable_primes[i] < required) \ + i++; \ +\ + return cmc_hashtable_primes[i]; \ } #endif /* CMC_CMC_HASHMULTIMAP_H */ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index 91d80de..3ebb891 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -39,890 +39,816 @@ /** * Core HashMultiSet implementation */ -#define CMC_CMC_HASHMULTISET_CORE(PARAMS) \ +#define CMC_CMC_HASHMULTISET_CORE(PARAMS) \ CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) \ CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) #define CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_CMC_HASHMULTISET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_CMC_HASHMULTISET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTISET_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* HashMultiset Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ - \ - /* Current Array Capcity */ \ - size_t capacity; \ - \ - /* Current amount of unique elements */ \ - size_t count; \ - \ - /* Total amount of elements taking into account their multiplicity */ \ - size_t cardinality; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Key function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry element */ \ - V value; \ - \ - /* The element's multiplicity */ \ - size_t multiplicity; \ - \ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ - \ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _set_); \ - void CMC_(PFX, _free)(struct SNAME * _set_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _set_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ +#define CMC_CMC_HASHMULTISET_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* HashMultiset Structure */ \ + struct SNAME \ + { \ + /* Array of Entries */ \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ +\ + /* Current Array Capcity */ \ + size_t capacity; \ +\ + /* Current amount of unique elements */ \ + size_t count; \ +\ + /* Total amount of elements taking into account their multiplicity */ \ + size_t cardinality; \ +\ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Key function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry element */ \ + V value; \ +\ + /* The element's multiplicity */ \ + size_t multiplicity; \ +\ + /* The distance of this node to its original position, used by */ \ + /* robin-hood hashing */ \ + size_t dist; \ +\ + /* The sate of this node (DELETED, EMPTY, FILLED) */ \ + enum cmc_entry_state state; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _set_); \ + void CMC_(PFX, _free)(struct SNAME * _set_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count); \ - bool CMC_(PFX, _update)(struct SNAME * _set_, V value, \ - size_t multiplicity); \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ - size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ - size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _set_); \ - bool CMC_(PFX, _full)(struct SNAME * _set_); \ - size_t CMC_(PFX, _count)(struct SNAME * _set_); \ - size_t CMC_(PFX, _cardinality)(struct SNAME * _set_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ - double CMC_(PFX, _load)(struct SNAME * _set_); \ - int CMC_(PFX, _flag)(struct SNAME * _set_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _update)(struct SNAME * _set_, V value, size_t multiplicity); \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ + size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ + size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _set_); \ + bool CMC_(PFX, _full)(struct SNAME * _set_); \ + size_t CMC_(PFX, _count)(struct SNAME * _set_); \ + size_t CMC_(PFX, _cardinality)(struct SNAME * _set_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ + double CMC_(PFX, _load)(struct SNAME * _set_); \ + int CMC_(PFX, _flag)(struct SNAME * _set_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTISET_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, \ - V value); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, \ - bool *new_node); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_set_) \ - return NULL; \ - \ - _set_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ - \ - if (!_set_->buffer) \ - { \ - alloc->free(_set_); \ - return NULL; \ - } \ - \ - _set_->count = 0; \ - _set_->cardinality = 0; \ - _set_->capacity = real_capacity; \ - _set_->load = load; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - _set_->callbacks = NULL; \ - \ - return _set_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_set_) \ - return NULL; \ - \ - _set_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ - \ - if (!_set_->buffer) \ - { \ - alloc->free(_set_); \ - return NULL; \ - } \ - \ - _set_->count = 0; \ - _set_->cardinality = 0; \ - _set_->capacity = real_capacity; \ - _set_->load = load; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - _set_->callbacks = callbacks; \ - \ - return _set_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _set_) \ - { \ - if (_set_->f_val->free) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - _set_->f_val->free(entry->value); \ - } \ - } \ - } \ - \ - memset(_set_->buffer, 0, \ - sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ - \ - _set_->count = 0; \ - _set_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _set_) \ - { \ - if (_set_->f_val->free) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - _set_->f_val->free(entry->value); \ - } \ - } \ - } \ - \ - _set_->alloc->free(_set_->buffer); \ - _set_->alloc->free(_set_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _set_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _set_->alloc = &cmc_alloc_node_default; \ - else \ - _set_->alloc = alloc; \ - \ - _set_->callbacks = callbacks; \ - \ - _set_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ - { \ - bool new_node; \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ - \ - if (!entry) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - if (!new_node) \ - entry->multiplicity++; \ - \ - _set_->cardinality++; \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->create) \ - _set_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count) \ - { \ - if (count == 0) \ - goto success; \ - \ - bool new_node; \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ - \ - if (!entry) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - if (new_node) \ - entry->multiplicity = count; \ - else \ - entry->multiplicity += count; \ - \ - _set_->cardinality += count; \ - \ - success: \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->create) \ - _set_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _update)(struct SNAME * _set_, V value, \ - size_t multiplicity) \ - { \ - if (multiplicity == 0) \ - { \ - /* Effectively delete the entry */ \ - struct CMC_DEF_ENTRY(SNAME) *result = \ - CMC_(PFX, _impl_get_entry)(_set_, value); \ - \ - if (!result) \ +#define CMC_CMC_HASHMULTISET_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, V value); \ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, bool *new_node); \ + static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capaccapacity, load, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity == 0 || load <= 0 || load >= 1) \ + return NULL; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ +\ + if (!f_val) \ + return NULL; \ +\ + size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_set_) \ + return NULL; \ +\ + _set_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ +\ + if (!_set_->buffer) \ + { \ + alloc->free(_set_); \ + return NULL; \ + } \ +\ + _set_->count = 0; \ + _set_->cardinality = 0; \ + _set_->capacity = real_capacity; \ + _set_->load = load; \ + _set_->flag = CMC_FLAG_OK; \ + _set_->f_val = f_val; \ + _set_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ +\ + return _set_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _set_) \ + { \ + if (_set_->f_val->free) \ + { \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ +\ + if (entry->state == CMC_ES_FILLED) \ + { \ + _set_->f_val->free(entry->value); \ + } \ + } \ + } \ +\ + memset(_set_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ +\ + _set_->count = 0; \ + _set_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _set_) \ + { \ + if (_set_->f_val->free) \ + { \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ +\ + if (entry->state == CMC_ES_FILLED) \ + { \ + _set_->f_val->free(entry->value); \ + } \ + } \ + } \ +\ + _set_->alloc->free(_set_->buffer); \ + _set_->alloc->free(_set_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _set_->alloc = &cmc_alloc_node_default; \ + else \ + _set_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ +\ + _set_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ + { \ + bool new_node; \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ +\ + if (!entry) \ + { \ + _set_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + if (!new_node) \ + entry->multiplicity++; \ +\ + _set_->cardinality++; \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->create) \ + _set_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count) \ + { \ + if (count == 0) \ + goto success; \ +\ + bool new_node; \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ +\ + if (!entry) \ + { \ + _set_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + if (new_node) \ + entry->multiplicity = count; \ + else \ + entry->multiplicity += count; \ +\ + _set_->cardinality += count; \ +\ + success: \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->create) \ + _set_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _update)(struct SNAME * _set_, V value, size_t multiplicity) \ + { \ + if (multiplicity == 0) \ + { \ + /* Effectively delete the entry */ \ + struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \ +\ + if (!result) \ /* If no entry was found then its multiplicity is already 0 */ \ - goto success; \ - \ - _set_->count--; \ - _set_->cardinality -= result->multiplicity; \ - \ - result->value = (V){ 0 }; \ - result->multiplicity = 0; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ - \ - goto success; \ - } \ - \ - bool new_node; \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ - \ - if (!entry) \ - return false; \ - \ - if (new_node) \ - _set_->cardinality++; \ - \ - _set_->cardinality = \ - (_set_->cardinality - entry->multiplicity) + multiplicity; \ - \ - entry->multiplicity = multiplicity; \ - \ - success: \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->update) \ - _set_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *result = \ - CMC_(PFX, _impl_get_entry)(_set_, value); \ - \ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - if (result->multiplicity > 1) \ - result->multiplicity--; \ - else \ - { \ - result->value = (V){ 0 }; \ - result->multiplicity = 0; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ - \ - _set_->count--; \ - } \ - \ - _set_->cardinality--; \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->delete) \ - _set_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *result = \ - CMC_(PFX, _impl_get_entry)(_set_, value); \ - \ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ - \ - size_t removed = result->multiplicity; \ - \ - result->value = (V){ 0 }; \ - result->multiplicity = 0; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ - \ - _set_->count--; \ - _set_->cardinality -= removed; \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->delete) \ - _set_->callbacks->delete (); \ - \ - return removed; \ - } \ - \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - V max_val; \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ - \ - /* TODO transform this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V result = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ - \ - if (index == 0) \ - max_val = result; \ - else if (_set_->f_val->cmp(result, max_val) > 0) \ - max_val = result; \ - } \ - \ - if (value) \ - *value = max_val; \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - V min_val; \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ - \ - /* TODO transform this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V result = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ - \ - if (index == 0) \ - min_val = result; \ - else if (_set_->f_val->cmp(result, min_val) < 0) \ - min_val = result; \ - } \ - \ - if (value) \ - *value = min_val; \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return true; \ - } \ - \ - size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_set_, value); \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - if (!entry) \ - return 0; \ - \ - return entry->multiplicity; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ - { \ - _set_->flag = CMC_FLAG_OK; \ - \ - bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _set_) \ - { \ - return _set_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _set_) \ - { \ - return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _set_) \ - { \ - return _set_->count; \ - } \ - \ - size_t CMC_(PFX, _cardinality)(struct SNAME * _set_) \ - { \ - return _set_->cardinality; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \ - { \ - return _set_->capacity; \ - } \ - \ - double CMC_(PFX, _load)(struct SNAME * _set_) \ - { \ - return _set_->load; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _set_) \ - { \ - return _set_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \ - { \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->capacity == capacity) \ - goto success; \ - \ - if (_set_->capacity > capacity / _set_->load) \ - goto success; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _set_->load) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ - \ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _set_->count / _set_->load) \ - { \ - _set_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - /* No callbacks since _new_set_ is just a temporary hashtable */ \ - struct SNAME *_new_set_ = CMC_(PFX, _new_custom)( \ - capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \ - \ - if (!_new_set_) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ - \ - /* TODO transform this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - CMC_(PFX, _insert_many) \ - (_new_set_, CMC_(PFX, _iter_value)(&iter), \ - CMC_(PFX, _iter_multiplicity)(&iter)); \ - } \ - \ - if (_set_->count != _new_set_->count) \ - { \ - CMC_(PFX, _free)(_new_set_); \ - \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \ - _set_->buffer = _new_set_->buffer; \ - _new_set_->buffer = tmp_b; \ - \ - size_t tmp_c = _set_->capacity; \ - _set_->capacity = _new_set_->capacity; \ - _new_set_->capacity = tmp_c; \ - \ - /* Prevent the set from freeing the data */ \ - _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ - \ - CMC_(PFX, _free)(_new_set_); \ - \ - success: \ - \ - if (_set_->callbacks && _set_->callbacks->resize) \ - _set_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _set_->capacity * _set_->load, _set_->load, _set_->f_val, \ - _set_->alloc, _set_->callbacks); \ - \ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_set_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \ - \ - if (scan->state != CMC_ES_EMPTY) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *target = \ - &(result->buffer[i]); \ - \ - if (scan->state == CMC_ES_DELETED) \ - target->state = CMC_ES_DELETED; \ - else \ - { \ - target->state = scan->state; \ - target->dist = scan->dist; \ - target->multiplicity = scan->multiplicity; \ - \ - target->value = _set_->f_val->cpy(scan->value); \ - } \ - } \ - } \ - } \ - else \ - memcpy(result->buffer, _set_->buffer, \ - sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ - \ - result->count = _set_->count; \ - result->cardinality = _set_->cardinality; \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - if (_set1_->count != _set2_->count) \ - return false; \ - \ - if (_set1_->cardinality != _set2_->cardinality) \ - return false; \ - \ - if (_set1_->count == 0) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)( \ - _set2_, CMC_(PFX, _iter_value)(&iter)); \ - \ - if (!entry) \ - return false; \ - \ - if (entry->multiplicity != CMC_(PFX, _iter_multiplicity)(&iter)) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, \ - V value) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_set_, value); \ - \ - if (!entry) \ - return 0; \ - \ - return entry->multiplicity; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, \ - bool *new_node) \ - { \ - /* If the entry already exists simply return it as we might do */ \ - /* something with it. This function only guarantees that there is */ \ - /* a valid entry for a given value */ \ - \ - *new_node = false; \ - \ - struct CMC_DEF_ENTRY(SNAME) *entry = \ - CMC_(PFX, _impl_get_entry)(_set_, value); \ - \ - if (entry != NULL) \ - return entry; \ - \ - *new_node = true; \ - \ - if (CMC_(PFX, _full)(_set_)) \ - { \ - if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \ - return NULL; \ - } \ - \ - size_t hash = _set_->f_val->hash(value); \ - size_t original_pos = hash % _set_->capacity; \ - size_t pos = original_pos; \ - /* Current multiplicity. Might change due to robin hood hashing */ \ - size_t curr_mul = 1; \ - \ - struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ - struct CMC_DEF_ENTRY(SNAME) *to_return = NULL; \ - \ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->value = value; \ - target->multiplicity = curr_mul; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ - \ - to_return = target; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - target = &(_set_->buffer[pos % _set_->capacity]); \ - \ - if (target->state == CMC_ES_EMPTY || \ - target->state == CMC_ES_DELETED) \ - { \ - target->value = value; \ - target->multiplicity = curr_mul; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ - \ - if (!to_return) \ - to_return = target; \ - \ - break; \ - } \ - else if (target->dist < pos - original_pos) \ - { \ - /* Swap everything */ \ - V tmp = target->value; \ - size_t tmp_dist = target->dist; \ - size_t tmp_mul = target->multiplicity; \ - \ - target->value = value; \ - target->dist = pos - original_pos; \ - target->multiplicity = curr_mul; \ - \ - value = tmp; \ - original_pos = pos - tmp_dist; \ - curr_mul = tmp_mul; \ - \ - if (!to_return) \ - to_return = target; \ - } \ - } \ - } \ - \ - _set_->count++; \ - \ - return to_return; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ - { \ - size_t hash = _set_->f_val->hash(value); \ - size_t pos = hash % _set_->capacity; \ - \ - struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ - \ - while (target->state == CMC_ES_FILLED || \ - target->state == CMC_ES_DELETED) \ - { \ - if (_set_->f_val->cmp(target->value, value) == 0) \ - return target; \ - \ - pos++; \ - target = &(_set_->buffer[pos % _set_->capacity]); \ - } \ - \ - return NULL; \ - } \ - \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = \ - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ - \ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ - \ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ - \ - return cmc_hashtable_primes[i]; \ + goto success; \ +\ + _set_->count--; \ + _set_->cardinality -= result->multiplicity; \ +\ + result->value = (V){ 0 }; \ + result->multiplicity = 0; \ + result->dist = 0; \ + result->state = CMC_ES_DELETED; \ +\ + goto success; \ + } \ +\ + bool new_node; \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ +\ + if (!entry) \ + return false; \ +\ + if (new_node) \ + _set_->cardinality++; \ +\ + _set_->cardinality = (_set_->cardinality - entry->multiplicity) + multiplicity; \ +\ + entry->multiplicity = multiplicity; \ +\ + success: \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->update) \ + _set_->callbacks->update(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \ +\ + if (!result) \ + { \ + _set_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + if (result->multiplicity > 1) \ + result->multiplicity--; \ + else \ + { \ + result->value = (V){ 0 }; \ + result->multiplicity = 0; \ + result->dist = 0; \ + result->state = CMC_ES_DELETED; \ +\ + _set_->count--; \ + } \ +\ + _set_->cardinality--; \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->delete) \ + _set_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \ +\ + if (!result) \ + { \ + _set_->flag = CMC_FLAG_NOT_FOUND; \ + return 0; \ + } \ +\ + size_t removed = result->multiplicity; \ +\ + result->value = (V){ 0 }; \ + result->multiplicity = 0; \ + result->dist = 0; \ + result->state = CMC_ES_DELETED; \ +\ + _set_->count--; \ + _set_->cardinality -= removed; \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->delete) \ + _set_->callbacks->delete (); \ +\ + return removed; \ + } \ +\ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + V max_val; \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ +\ + /* TODO transform this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V result = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ +\ + if (index == 0) \ + max_val = result; \ + else if (_set_->f_val->cmp(result, max_val) > 0) \ + max_val = result; \ + } \ +\ + if (value) \ + *value = max_val; \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + V min_val; \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ +\ + /* TODO transform this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V result = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ +\ + if (index == 0) \ + min_val = result; \ + else if (_set_->f_val->cmp(result, min_val) < 0) \ + min_val = result; \ + } \ +\ + if (value) \ + *value = min_val; \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return true; \ + } \ +\ + size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + if (!entry) \ + return 0; \ +\ + return entry->multiplicity; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ + { \ + _set_->flag = CMC_FLAG_OK; \ +\ + bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _set_) \ + { \ + return _set_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _set_) \ + { \ + return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _set_) \ + { \ + return _set_->count; \ + } \ +\ + size_t CMC_(PFX, _cardinality)(struct SNAME * _set_) \ + { \ + return _set_->cardinality; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \ + { \ + return _set_->capacity; \ + } \ +\ + double CMC_(PFX, _load)(struct SNAME * _set_) \ + { \ + return _set_->load; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _set_) \ + { \ + return _set_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \ + { \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->capacity == capacity) \ + goto success; \ +\ + if (_set_->capacity > capacity / _set_->load) \ + goto success; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * _set_->load) \ + { \ + _set_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + /* Calculate required capacity based on the prime numbers */ \ + size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ +\ + /* Not possible to shrink with current available prime numbers */ \ + if (theoretical_size < _set_->count / _set_->load) \ + { \ + _set_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + /* No callbacks since _new_set_ is just a temporary hashtable */ \ + struct SNAME *_new_set_ = CMC_(PFX, _new_custom)(capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \ +\ + if (!_new_set_) \ + { \ + _set_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ +\ + /* TODO transform this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + CMC_(PFX, _insert_many) \ + (_new_set_, CMC_(PFX, _iter_value)(&iter), CMC_(PFX, _iter_multiplicity)(&iter)); \ + } \ +\ + if (_set_->count != _new_set_->count) \ + { \ + CMC_(PFX, _free)(_new_set_); \ +\ + _set_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \ + _set_->buffer = _new_set_->buffer; \ + _new_set_->buffer = tmp_b; \ +\ + size_t tmp_c = _set_->capacity; \ + _set_->capacity = _new_set_->capacity; \ + _new_set_->capacity = tmp_c; \ +\ + /* Prevent the set from freeing the data */ \ + _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ +\ + CMC_(PFX, _free)(_new_set_); \ +\ + success: \ +\ + if (_set_->callbacks && _set_->callbacks->resize) \ + _set_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ + { \ + struct SNAME *result = \ + CMC_(PFX, _new_custom)(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, NULL); \ +\ + if (!result) \ + { \ + _set_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \ +\ + if (_set_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \ +\ + if (scan->state != CMC_ES_EMPTY) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \ +\ + if (scan->state == CMC_ES_DELETED) \ + target->state = CMC_ES_DELETED; \ + else \ + { \ + target->state = scan->state; \ + target->dist = scan->dist; \ + target->multiplicity = scan->multiplicity; \ +\ + target->value = _set_->f_val->cpy(scan->value); \ + } \ + } \ + } \ + } \ + else \ + memcpy(result->buffer, _set_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ +\ + result->count = _set_->count; \ + result->cardinality = _set_->cardinality; \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ +\ + if (_set1_->count != _set2_->count) \ + return false; \ +\ + if (_set1_->cardinality != _set2_->cardinality) \ + return false; \ +\ + if (_set1_->count == 0) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set2_, CMC_(PFX, _iter_value)(&iter)); \ +\ + if (!entry) \ + return false; \ +\ + if (entry->multiplicity != CMC_(PFX, _iter_multiplicity)(&iter)) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, V value) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \ +\ + if (!entry) \ + return 0; \ +\ + return entry->multiplicity; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * \ + CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, bool *new_node) \ + { \ + /* If the entry already exists simply return it as we might do */ \ + /* something with it. This function only guarantees that there is */ \ + /* a valid entry for a given value */ \ +\ + *new_node = false; \ +\ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \ +\ + if (entry != NULL) \ + return entry; \ +\ + *new_node = true; \ +\ + if (CMC_(PFX, _full)(_set_)) \ + { \ + if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \ + return NULL; \ + } \ +\ + size_t hash = _set_->f_val->hash(value); \ + size_t original_pos = hash % _set_->capacity; \ + size_t pos = original_pos; \ + /* Current multiplicity. Might change due to robin hood hashing */ \ + size_t curr_mul = 1; \ +\ + struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ + struct CMC_DEF_ENTRY(SNAME) *to_return = NULL; \ +\ + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ + { \ + target->value = value; \ + target->multiplicity = curr_mul; \ + target->dist = pos - original_pos; \ + target->state = CMC_ES_FILLED; \ +\ + to_return = target; \ + } \ + else \ + { \ + while (true) \ + { \ + pos++; \ + target = &(_set_->buffer[pos % _set_->capacity]); \ +\ + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ + { \ + target->value = value; \ + target->multiplicity = curr_mul; \ + target->dist = pos - original_pos; \ + target->state = CMC_ES_FILLED; \ +\ + if (!to_return) \ + to_return = target; \ +\ + break; \ + } \ + else if (target->dist < pos - original_pos) \ + { \ + /* Swap everything */ \ + V tmp = target->value; \ + size_t tmp_dist = target->dist; \ + size_t tmp_mul = target->multiplicity; \ +\ + target->value = value; \ + target->dist = pos - original_pos; \ + target->multiplicity = curr_mul; \ +\ + value = tmp; \ + original_pos = pos - tmp_dist; \ + curr_mul = tmp_mul; \ +\ + if (!to_return) \ + to_return = target; \ + } \ + } \ + } \ +\ + _set_->count++; \ +\ + return to_return; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ + { \ + size_t hash = _set_->f_val->hash(value); \ + size_t pos = hash % _set_->capacity; \ +\ + struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ +\ + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \ + { \ + if (_set_->f_val->cmp(target->value, value) == 0) \ + return target; \ +\ + pos++; \ + target = &(_set_->buffer[pos % _set_->capacity]); \ + } \ +\ + return NULL; \ + } \ +\ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ + { \ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ +\ + if (cmc_hashtable_primes[count - 1] < required) \ + return required; \ +\ + size_t i = 0; \ + while (cmc_hashtable_primes[i] < required) \ + i++; \ +\ + return cmc_hashtable_primes[i]; \ } #endif /* CMC_CMC_HASHMULTISET_H */ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 08ac2af..d8d9a3c 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -32,658 +32,601 @@ /** * Core HashSet implementation */ -#define CMC_CMC_HASHSET_CORE(PARAMS) \ +#define CMC_CMC_HASHSET_CORE(PARAMS) \ CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \ CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) -#define CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \ + CMC_CMC_HASHSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) \ + CMC_CMC_HASHSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Hashset Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ - \ - /* Current Array Capcity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry value */ \ - V value; \ - \ +#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* Hashset Structure */ \ + struct SNAME \ + { \ + /* Array of Entries */ \ + struct CMC_DEF_ENTRY(SNAME) * buffer; \ +\ + /* Current Array Capcity */ \ + size_t capacity; \ +\ + /* Current amount of elements */ \ + size_t count; \ +\ + /* Load factor in range (0.0, 1.0) */ \ + double load; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + struct CMC_DEF_ENTRY(SNAME) \ + { \ + /* Entry value */ \ + V value; \ +\ /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ - \ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _set_); \ - void CMC_(PFX, _free)(struct SNAME * _set_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _set_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _set_); \ - bool CMC_(PFX, _full)(struct SNAME * _set_); \ - size_t CMC_(PFX, _count)(struct SNAME * _set_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ - double CMC_(PFX, _load)(struct SNAME * _set_); \ - int CMC_(PFX, _flag)(struct SNAME * _set_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + /* robin-hood hashing */ \ + size_t dist; \ +\ + /* The sate of this node (DELETED, EMPTY, FILLED) */ \ + enum cmc_entry_state state; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _set_); \ + void CMC_(PFX, _free)(struct SNAME * _set_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _set_); \ + bool CMC_(PFX, _full)(struct SNAME * _set_); \ + size_t CMC_(PFX, _count)(struct SNAME * _set_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ + double CMC_(PFX, _load)(struct SNAME * _set_); \ + int CMC_(PFX, _flag)(struct SNAME * _set_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHSET_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_set_) \ - return NULL; \ - \ - _set_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ - \ - if (!_set_->buffer) \ - { \ - alloc->free(_set_); \ - return NULL; \ - } \ - \ - _set_->count = 0; \ - _set_->capacity = real_capacity; \ - _set_->load = load; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - _set_->callbacks = NULL; \ - \ - return _set_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - size_t real_capacity = \ - CMC_(PFX, _impl_calculate_size)(capacity / load); \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_set_) \ - return NULL; \ - \ - _set_->buffer = \ - alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ - \ - if (!_set_->buffer) \ - { \ - alloc->free(_set_); \ - return NULL; \ - } \ - \ - _set_->count = 0; \ - _set_->capacity = real_capacity; \ - _set_->load = load; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - _set_->callbacks = callbacks; \ - \ - return _set_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _set_) \ - { \ - if (_set_->f_val->free) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - _set_->f_val->free(entry->value); \ - } \ - } \ - } \ - \ - memset(_set_->buffer, 0, \ - sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ - \ - _set_->count = 0; \ - _set_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _set_) \ - { \ - if (_set_->f_val->free) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - _set_->f_val->free(entry->value); \ - } \ - } \ - } \ - \ - _set_->alloc->free(_set_->buffer); \ - _set_->alloc->free(_set_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _set_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _set_->alloc = &cmc_alloc_node_default; \ - else \ - _set_->alloc = alloc; \ - \ - _set_->callbacks = callbacks; \ - \ - _set_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _full)(_set_)) \ - { \ - if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \ - return false; \ - } \ - \ - if (CMC_(PFX, _impl_get_entry)(_set_, value) != NULL) \ - { \ - _set_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - \ - size_t hash = _set_->f_val->hash(value); \ - size_t original_pos = hash % _set_->capacity; \ - size_t pos = original_pos; \ - \ - struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ - \ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->value = value; \ - target->dist = 0; \ - target->state = CMC_ES_FILLED; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - target = &(_set_->buffer[pos % _set_->capacity]); \ - \ - if (target->state == CMC_ES_EMPTY || \ - target->state == CMC_ES_DELETED) \ - { \ - target->value = value; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ - \ - break; \ - } \ - else if (target->dist < pos - original_pos) \ - { \ - V tmp = target->value; \ - size_t tmp_dist = target->dist; \ - \ - target->value = value; \ - target->dist = pos - original_pos; \ - \ - value = tmp; \ - original_pos = pos - tmp_dist; \ - } \ - } \ - } \ - \ - _set_->count++; \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->create) \ - _set_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *result = \ - CMC_(PFX, _impl_get_entry)(_set_, value); \ - \ - if (result == NULL) \ - { \ - _set_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - result->value = (V){ 0 }; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ - \ - _set_->count--; \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->delete) \ - _set_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - V max_value; \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ - \ - /* TODO turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V result = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ - \ - if (index == 0) \ - max_value = result; \ - else if (_set_->f_val->cmp(result, max_value) > 0) \ - max_value = result; \ - } \ - \ - if (value) \ - *value = max_value; \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - V min_value; \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ - \ - /* TODO turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V result = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ - \ - if (index == 0) \ - min_value = result; \ - else if (_set_->f_val->cmp(result, min_value) < 0) \ - min_value = result; \ - } \ - \ - if (value) \ - *value = min_value; \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ - { \ - _set_->flag = CMC_FLAG_OK; \ - \ - bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _set_) \ - { \ - return _set_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _set_) \ - { \ - return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _set_) \ - { \ - return _set_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \ - { \ - return _set_->capacity; \ - } \ - \ - double CMC_(PFX, _load)(struct SNAME * _set_) \ - { \ - return _set_->load; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _set_) \ - { \ - return _set_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \ - { \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->capacity == capacity) \ - goto success; \ - \ - if (_set_->capacity > capacity / _set_->load) \ - goto success; \ - \ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _set_->load) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ - \ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _set_->count / _set_->load) \ - { \ - _set_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - /* No callbacks since _new_set_ is just a temporary hashtable */ \ - struct SNAME *_new_set_ = CMC_(PFX, _new_custom)( \ - capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \ - \ - if (!_new_set_) \ - { \ - _set_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ - \ - /* TODO turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - /* TODO check for error */ \ - CMC_(PFX, _insert)(_new_set_, value); \ - } \ - \ - /* Unlikely */ \ - if (_set_->count != _new_set_->count) \ - { \ - CMC_(PFX, _free)(_new_set_); \ - \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \ - _set_->buffer = _new_set_->buffer; \ - _new_set_->buffer = tmp_b; \ - \ - size_t tmp_c = _set_->capacity; \ - _set_->capacity = _new_set_->capacity; \ - _new_set_->capacity = tmp_c; \ - \ - /* Prevent the set from freeing the data */ \ - _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ - \ - CMC_(PFX, _free)(_new_set_); \ - \ - success: \ - \ - if (_set_->callbacks && _set_->callbacks->resize) \ - _set_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _set_->capacity * _set_->load, _set_->load, _set_->f_val, \ - _set_->alloc, _set_->callbacks); \ - \ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_set_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \ - \ - if (scan->state != CMC_ES_EMPTY) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *target = \ - &(result->buffer[i]); \ - \ - if (scan->state == CMC_ES_DELETED) \ - target->state = CMC_ES_DELETED; \ - else \ - { \ - target->state = scan->state; \ - target->dist = scan->dist; \ - \ - target->value = _set_->f_val->cpy(scan->value); \ - } \ - } \ - } \ - } \ - else \ - memcpy(result->buffer, _set_->buffer, \ - sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ - \ - result->count = _set_->count; \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - if (_set1_->count != _set2_->count) \ - return false; \ - \ - if (_set1_->count == 0) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - /* TODO optimize this loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - if (CMC_(PFX, _impl_get_entry)( \ - _set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ - { \ - size_t hash = _set_->f_val->hash(value); \ - size_t pos = hash % _set_->capacity; \ - \ - struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ - \ - while (target->state == CMC_ES_FILLED || \ - target->state == CMC_ES_DELETED) \ - { \ - if (_set_->f_val->cmp(target->value, value) == 0) \ - return target; \ - \ - pos++; \ - target = &(_set_->buffer[pos % _set_->capacity]); \ - } \ - \ - return NULL; \ - } \ - \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = \ - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ - \ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ - \ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ - \ - return cmc_hashtable_primes[i]; \ +#define CMC_CMC_HASHSET_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, load, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity == 0 || load <= 0 || load >= 1) \ + return NULL; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * load) \ + return NULL; \ +\ + if (!f_val) \ + return NULL; \ +\ + size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_set_) \ + return NULL; \ +\ + _set_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ +\ + if (!_set_->buffer) \ + { \ + alloc->free(_set_); \ + return NULL; \ + } \ +\ + _set_->count = 0; \ + _set_->capacity = real_capacity; \ + _set_->load = load; \ + _set_->flag = CMC_FLAG_OK; \ + _set_->f_val = f_val; \ + _set_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ +\ + return _set_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _set_) \ + { \ + if (_set_->f_val->free) \ + { \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ +\ + if (entry->state == CMC_ES_FILLED) \ + { \ + _set_->f_val->free(entry->value); \ + } \ + } \ + } \ +\ + memset(_set_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ +\ + _set_->count = 0; \ + _set_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _set_) \ + { \ + if (_set_->f_val->free) \ + { \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ +\ + if (entry->state == CMC_ES_FILLED) \ + { \ + _set_->f_val->free(entry->value); \ + } \ + } \ + } \ +\ + _set_->alloc->free(_set_->buffer); \ + _set_->alloc->free(_set_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _set_->alloc = &cmc_alloc_node_default; \ + else \ + _set_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ +\ + _set_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ + { \ + if (CMC_(PFX, _full)(_set_)) \ + { \ + if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \ + return false; \ + } \ +\ + if (CMC_(PFX, _impl_get_entry)(_set_, value) != NULL) \ + { \ + _set_->flag = CMC_FLAG_DUPLICATE; \ + return false; \ + } \ +\ + size_t hash = _set_->f_val->hash(value); \ + size_t original_pos = hash % _set_->capacity; \ + size_t pos = original_pos; \ +\ + struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ +\ + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ + { \ + target->value = value; \ + target->dist = 0; \ + target->state = CMC_ES_FILLED; \ + } \ + else \ + { \ + while (true) \ + { \ + pos++; \ + target = &(_set_->buffer[pos % _set_->capacity]); \ +\ + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ + { \ + target->value = value; \ + target->dist = pos - original_pos; \ + target->state = CMC_ES_FILLED; \ +\ + break; \ + } \ + else if (target->dist < pos - original_pos) \ + { \ + V tmp = target->value; \ + size_t tmp_dist = target->dist; \ +\ + target->value = value; \ + target->dist = pos - original_pos; \ +\ + value = tmp; \ + original_pos = pos - tmp_dist; \ + } \ + } \ + } \ +\ + _set_->count++; \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->create) \ + _set_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \ +\ + if (result == NULL) \ + { \ + _set_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + result->value = (V){ 0 }; \ + result->dist = 0; \ + result->state = CMC_ES_DELETED; \ +\ + _set_->count--; \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->delete) \ + _set_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + V max_value; \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ +\ + /* TODO turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V result = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ +\ + if (index == 0) \ + max_value = result; \ + else if (_set_->f_val->cmp(result, max_value) > 0) \ + max_value = result; \ + } \ +\ + if (value) \ + *value = max_value; \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + V min_value; \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ +\ + /* TODO turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V result = CMC_(PFX, _iter_value)(&iter); \ + size_t index = CMC_(PFX, _iter_index)(&iter); \ +\ + if (index == 0) \ + min_value = result; \ + else if (_set_->f_val->cmp(result, min_value) < 0) \ + min_value = result; \ + } \ +\ + if (value) \ + *value = min_value; \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ + { \ + _set_->flag = CMC_FLAG_OK; \ +\ + bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _set_) \ + { \ + return _set_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _set_) \ + { \ + return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _set_) \ + { \ + return _set_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \ + { \ + return _set_->capacity; \ + } \ +\ + double CMC_(PFX, _load)(struct SNAME * _set_) \ + { \ + return _set_->load; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _set_) \ + { \ + return _set_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \ + { \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->capacity == capacity) \ + goto success; \ +\ + if (_set_->capacity > capacity / _set_->load) \ + goto success; \ +\ + /* Prevent integer overflow */ \ + if (capacity >= UINTMAX_MAX * _set_->load) \ + { \ + _set_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + /* Calculate required capacity based on the prime numbers */ \ + size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ +\ + /* Not possible to shrink with current available prime numbers */ \ + if (theoretical_size < _set_->count / _set_->load) \ + { \ + _set_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + /* No callbacks since _new_set_ is just a temporary hashtable */ \ + struct SNAME *_new_set_ = CMC_(PFX, _new_custom)(capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \ +\ + if (!_new_set_) \ + { \ + _set_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ +\ + /* TODO turn this into a normal loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + /* TODO check for error */ \ + CMC_(PFX, _insert)(_new_set_, value); \ + } \ +\ + /* Unlikely */ \ + if (_set_->count != _new_set_->count) \ + { \ + CMC_(PFX, _free)(_new_set_); \ +\ + _set_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \ + _set_->buffer = _new_set_->buffer; \ + _new_set_->buffer = tmp_b; \ +\ + size_t tmp_c = _set_->capacity; \ + _set_->capacity = _new_set_->capacity; \ + _new_set_->capacity = tmp_c; \ +\ + /* Prevent the set from freeing the data */ \ + _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ +\ + CMC_(PFX, _free)(_new_set_); \ +\ + success: \ +\ + if (_set_->callbacks && _set_->callbacks->resize) \ + _set_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ + { \ + struct SNAME *result = \ + CMC_(PFX, _new_custom)(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, NULL); \ +\ + if (!result) \ + { \ + _set_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \ +\ + if (_set_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \ +\ + if (scan->state != CMC_ES_EMPTY) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \ +\ + if (scan->state == CMC_ES_DELETED) \ + target->state = CMC_ES_DELETED; \ + else \ + { \ + target->state = scan->state; \ + target->dist = scan->dist; \ +\ + target->value = _set_->f_val->cpy(scan->value); \ + } \ + } \ + } \ + } \ + else \ + memcpy(result->buffer, _set_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ +\ + result->count = _set_->count; \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ +\ + if (_set1_->count != _set2_->count) \ + return false; \ +\ + if (_set1_->count == 0) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + /* TODO optimize this loop */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + if (CMC_(PFX, _impl_get_entry)(_set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ + { \ + size_t hash = _set_->f_val->hash(value); \ + size_t pos = hash % _set_->capacity; \ +\ + struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ +\ + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \ + { \ + if (_set_->f_val->cmp(target->value, value) == 0) \ + return target; \ +\ + pos++; \ + target = &(_set_->buffer[pos % _set_->capacity]); \ + } \ +\ + return NULL; \ + } \ +\ + static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ + { \ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ +\ + if (cmc_hashtable_primes[count - 1] < required) \ + return required; \ +\ + size_t i = 0; \ + while (cmc_hashtable_primes[i] < required) \ + i++; \ +\ + return cmc_hashtable_primes[i]; \ } #endif /* CMC_CMC_HASHSET_H */ diff --git a/src/cmc/heap.h b/src/cmc/heap.h index e30cba8..adee37f 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -43,494 +43,442 @@ /** * Core Heap implementation */ -#define CMC_CMC_HEAP_CORE(PARAMS) \ +#define CMC_CMC_HEAP_CORE(PARAMS) \ CMC_CMC_HEAP_CORE_HEADER(PARAMS) \ CMC_CMC_HEAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_HEAP_CORE_HEADER(PARAMS) \ - CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_HEAP_CORE_HEADER(PARAMS) \ + CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_HEAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_HEAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Heap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements in the heap */ \ - size_t count; \ - \ - /* Heap order (MaxHeap or MinHeap) */ \ - enum cmc_heap_order HO; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, enum cmc_heap_order HO, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _heap_); \ - void CMC_(PFX, _free)(struct SNAME * _heap_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _heap_); \ - /* Element Access */ \ - V CMC_(PFX, _peek)(struct SNAME * _heap_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ - bool CMC_(PFX, _full)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ - int CMC_(PFX, _flag)(struct SNAME * _heap_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \ +#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* Heap Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ +\ + /* Current array capacity */ \ + size_t capacity; \ +\ + /* Current amount of elements in the heap */ \ + size_t count; \ +\ + /* Heap order (MaxHeap or MinHeap) */ \ + enum cmc_heap_order HO; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _heap_); \ + void CMC_(PFX, _free)(struct SNAME * _heap_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _heap_); \ + /* Element Access */ \ + V CMC_(PFX, _peek)(struct SNAME * _heap_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ + bool CMC_(PFX, _full)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ + int CMC_(PFX, _flag)(struct SNAME * _heap_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \ bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_HEAP_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, \ - size_t index); \ - static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, \ - size_t index); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity < 1) \ - return NULL; \ - \ - if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_heap_) \ - return NULL; \ - \ - _heap_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_heap_->buffer) \ - { \ - alloc->free(_heap_); \ - return NULL; \ - } \ - \ - _heap_->capacity = capacity; \ - _heap_->count = 0; \ - _heap_->HO = HO; \ - _heap_->flag = CMC_FLAG_OK; \ - _heap_->f_val = f_val; \ - _heap_->alloc = alloc; \ - _heap_->callbacks = NULL; \ - \ - return _heap_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, enum cmc_heap_order HO, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_heap_) \ - return NULL; \ - \ - _heap_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_heap_->buffer) \ - { \ - alloc->free(_heap_); \ - return NULL; \ - } \ - \ - _heap_->capacity = capacity; \ - _heap_->count = 0; \ - _heap_->HO = HO; \ - _heap_->flag = CMC_FLAG_OK; \ - _heap_->f_val = f_val; \ - _heap_->alloc = alloc; \ - _heap_->callbacks = callbacks; \ - \ - return _heap_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _heap_) \ - { \ - if (_heap_->f_val->free) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - _heap_->f_val->free(_heap_->buffer[i]); \ - } \ - } \ - \ - memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \ - \ - _heap_->count = 0; \ - _heap_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _heap_) \ - { \ - if (_heap_->f_val->free) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - _heap_->f_val->free(_heap_->buffer[i]); \ - } \ - } \ - \ - _heap_->alloc->free(_heap_->buffer); \ - _heap_->alloc->free(_heap_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _heap_->alloc = &cmc_alloc_node_default; \ - else \ - _heap_->alloc = alloc; \ - \ - _heap_->callbacks = callbacks; \ - \ - _heap_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \ - { \ - if (CMC_(PFX, _full)(_heap_)) \ - { \ - if (!CMC_(PFX, _resize)(_heap_, _heap_->count * 2)) \ - return false; \ - } \ - \ - _heap_->buffer[_heap_->count++] = value; \ - \ - if (_heap_->count > 1) \ - { \ - CMC_(PFX, _impl_float_up)(_heap_, _heap_->count - 1); \ - } \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->create) \ - _heap_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \ - _heap_->buffer[_heap_->count - 1] = (V){ 0 }; \ - \ - _heap_->count--; \ - \ - CMC_(PFX, _impl_float_down)(_heap_, 0); \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->delete) \ - _heap_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _peek)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ - \ - return _heap_->buffer[0]; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \ - { \ - _heap_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ - \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_) \ - { \ - return _heap_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _heap_) \ - { \ - return _heap_->count >= _heap_->capacity; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_) \ - { \ - return _heap_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \ - { \ - return _heap_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _heap_) \ - { \ - return _heap_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \ - { \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->capacity == capacity) \ - goto success; \ - \ - if (capacity < _heap_->count) \ - { \ - _heap_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - V *new_buffer = \ - _heap_->alloc->realloc(_heap_->buffer, sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - { \ - _heap_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - /* TODO zero out new slots */ \ - \ - _heap_->buffer = new_buffer; \ - _heap_->capacity = capacity; \ - \ - success: \ - \ - if (_heap_->callbacks && _heap_->callbacks->resize) \ - _heap_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, \ - _heap_->callbacks); \ - \ - if (!result) \ - { \ - _heap_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_heap_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); \ - } \ - else \ +#define CMC_CMC_HEAP_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, size_t index); \ + static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, size_t index); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, HO, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ +\ + if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \ + return NULL; \ +\ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_heap_) \ + return NULL; \ +\ + _heap_->buffer = alloc->calloc(capacity, sizeof(V)); \ +\ + if (!_heap_->buffer) \ + { \ + alloc->free(_heap_); \ + return NULL; \ + } \ +\ + _heap_->capacity = capacity; \ + _heap_->count = 0; \ + _heap_->HO = HO; \ + _heap_->flag = CMC_FLAG_OK; \ + _heap_->f_val = f_val; \ + _heap_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \ +\ + return _heap_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _heap_) \ + { \ + if (_heap_->f_val->free) \ + { \ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + _heap_->f_val->free(_heap_->buffer[i]); \ + } \ + } \ +\ + memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \ +\ + _heap_->count = 0; \ + _heap_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _heap_) \ + { \ + if (_heap_->f_val->free) \ + { \ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + _heap_->f_val->free(_heap_->buffer[i]); \ + } \ + } \ +\ + _heap_->alloc->free(_heap_->buffer); \ + _heap_->alloc->free(_heap_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _heap_->alloc = &cmc_alloc_node_default; \ + else \ + _heap_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \ +\ + _heap_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \ + { \ + if (CMC_(PFX, _full)(_heap_)) \ + { \ + if (!CMC_(PFX, _resize)(_heap_, _heap_->count * 2)) \ + return false; \ + } \ +\ + _heap_->buffer[_heap_->count++] = value; \ +\ + if (_heap_->count > 1) \ + { \ + CMC_(PFX, _impl_float_up)(_heap_, _heap_->count - 1); \ + } \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->create) \ + _heap_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove)(struct SNAME * _heap_) \ + { \ + if (CMC_(PFX, _empty)(_heap_)) \ + { \ + _heap_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \ + _heap_->buffer[_heap_->count - 1] = (V){ 0 }; \ +\ + _heap_->count--; \ +\ + CMC_(PFX, _impl_float_down)(_heap_, 0); \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->delete) \ + _heap_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _peek)(struct SNAME * _heap_) \ + { \ + if (CMC_(PFX, _empty)(_heap_)) \ + { \ + _heap_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->read) \ + _heap_->callbacks->read(); \ +\ + return _heap_->buffer[0]; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \ + { \ + _heap_->flag = CMC_FLAG_OK; \ +\ + bool result = false; \ +\ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) \ + { \ + result = true; \ + break; \ + } \ + } \ +\ + if (_heap_->callbacks && _heap_->callbacks->read) \ + _heap_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _heap_) \ + { \ + return _heap_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _heap_) \ + { \ + return _heap_->count >= _heap_->capacity; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _heap_) \ + { \ + return _heap_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \ + { \ + return _heap_->capacity; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _heap_) \ + { \ + return _heap_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \ + { \ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->capacity == capacity) \ + goto success; \ +\ + if (capacity < _heap_->count) \ + { \ + _heap_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + V *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(V) * capacity); \ +\ + if (!new_buffer) \ + { \ + _heap_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + /* TODO zero out new slots */ \ +\ + _heap_->buffer = new_buffer; \ + _heap_->capacity = capacity; \ +\ + success: \ +\ + if (_heap_->callbacks && _heap_->callbacks->resize) \ + _heap_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \ + { \ + struct SNAME *result = \ + CMC_(PFX, _new_custom)(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, NULL); \ +\ + if (!result) \ + { \ + _heap_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _heap_->callbacks); \ +\ + if (_heap_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _heap_->count; i++) \ + result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); \ + } \ + else \ memcpy(result->buffer, _heap_->buffer, sizeof(V) * _heap_->count); \ - \ - result->count = _heap_->count; \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \ - { \ - _heap1_->flag = CMC_FLAG_OK; \ - _heap2_->flag = CMC_FLAG_OK; \ - \ - if (_heap1_->count != _heap2_->count) \ - return false; \ - \ - for (size_t i = 0; i < _heap1_->count; i++) \ - { \ - if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != \ - 0) \ - return false; \ - } \ - \ - return true; \ - } \ - \ +\ + result->count = _heap_->count; \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \ + { \ + _heap1_->flag = CMC_FLAG_OK; \ + _heap2_->flag = CMC_FLAG_OK; \ +\ + if (_heap1_->count != _heap2_->count) \ + return false; \ +\ + for (size_t i = 0; i < _heap1_->count; i++) \ + { \ + if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) \ + return false; \ + } \ +\ + return true; \ + } \ +\ static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, size_t index) \ - { \ - /* Current index */ \ - size_t C = index; \ - V child = _heap_->buffer[C]; \ - V parent = _heap_->buffer[(index - 1) / 2]; \ - \ - int mod = _heap_->HO; \ - \ - while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) \ - { \ - /* Swap between C (current element) and its parent */ \ - V tmp = _heap_->buffer[C]; \ - _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; \ - _heap_->buffer[(C - 1) / 2] = tmp; \ - \ - /* Go to parent */ \ - C = (C - 1) / 2; \ - \ - /* Prevent the two lines below from accessing a negative index */ \ - if (C == 0) \ - break; \ - \ - child = _heap_->buffer[C]; \ - parent = _heap_->buffer[(C - 1) / 2]; \ - } \ - } \ - \ - static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, \ - size_t index) \ - { \ - int mod = _heap_->HO; \ - \ - while (index < _heap_->count) \ - { \ - size_t L = 2 * index + 1; \ - size_t R = 2 * index + 2; \ - size_t C = index; \ - \ - /* Determine if we swap with the left or right element */ \ - if (L < _heap_->count && \ - _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * \ - mod > \ - 0) \ - { \ - C = L; \ - } \ - \ - if (R < _heap_->count && \ - _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * \ - mod > \ - 0) \ - { \ - C = R; \ - } \ - \ + { \ + /* Current index */ \ + size_t C = index; \ + V child = _heap_->buffer[C]; \ + V parent = _heap_->buffer[(index - 1) / 2]; \ +\ + int mod = _heap_->HO; \ +\ + while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) \ + { \ + /* Swap between C (current element) and its parent */ \ + V tmp = _heap_->buffer[C]; \ + _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; \ + _heap_->buffer[(C - 1) / 2] = tmp; \ +\ + /* Go to parent */ \ + C = (C - 1) / 2; \ +\ + /* Prevent the two lines below from accessing a negative index */ \ + if (C == 0) \ + break; \ +\ + child = _heap_->buffer[C]; \ + parent = _heap_->buffer[(C - 1) / 2]; \ + } \ + } \ +\ + static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, size_t index) \ + { \ + int mod = _heap_->HO; \ +\ + while (index < _heap_->count) \ + { \ + size_t L = 2 * index + 1; \ + size_t R = 2 * index + 2; \ + size_t C = index; \ +\ + /* Determine if we swap with the left or right element */ \ + if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) \ + { \ + C = L; \ + } \ +\ + if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) \ + { \ + C = R; \ + } \ +\ /* Swap only if either left or right was picked, otherwise done */ \ - if (C != index) \ - { \ - V tmp = _heap_->buffer[index]; \ - _heap_->buffer[index] = _heap_->buffer[C]; \ - _heap_->buffer[C] = tmp; \ - \ - index = C; \ - } \ - else \ - break; \ - } \ + if (C != index) \ + { \ + V tmp = _heap_->buffer[index]; \ + _heap_->buffer[index] = _heap_->buffer[C]; \ + _heap_->buffer[C] = tmp; \ +\ + index = C; \ + } \ + else \ + break; \ + } \ } #endif /* CMC_CMC_HEAP_H */ diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index 0c05769..f141a6b 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -29,903 +29,850 @@ /** * Core IntervalHeap implementation */ -#define CMC_CMC_INTERVALHEAP_CORE(PARAMS) \ +#define CMC_CMC_INTERVALHEAP_CORE(PARAMS) \ CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) \ CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) #define CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_CMC_INTERVALHEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_CMC_INTERVALHEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* IntervalHeap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ - V (*buffer)[2]; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of pairs of values in the array */ \ - size_t size; \ - \ - /* Current amount of elements in the heap */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _heap_); \ - void CMC_(PFX, _free)(struct SNAME * _heap_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _remove_max)(struct SNAME * _heap_); \ - bool CMC_(PFX, _remove_min)(struct SNAME * _heap_); \ - /* Collection Update */ \ - bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value); \ - /* Element Access */ \ - V CMC_(PFX, _max)(struct SNAME * _heap_); \ - V CMC_(PFX, _min)(struct SNAME * _heap_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ - bool CMC_(PFX, _full)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ - int CMC_(PFX, _flag)(struct SNAME * _heap_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ +#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* IntervalHeap Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ + V (*buffer)[2]; \ +\ + /* Current array capacity */ \ + size_t capacity; \ +\ + /* Current amount of pairs of values in the array */ \ + size_t size; \ +\ + /* Current amount of elements in the heap */ \ + size_t count; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _heap_); \ + void CMC_(PFX, _free)(struct SNAME * _heap_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _remove_max)(struct SNAME * _heap_); \ + bool CMC_(PFX, _remove_min)(struct SNAME * _heap_); \ + /* Collection Update */ \ + bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value); \ + /* Element Access */ \ + V CMC_(PFX, _max)(struct SNAME * _heap_); \ + V CMC_(PFX, _min)(struct SNAME * _heap_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ + bool CMC_(PFX, _full)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ + int CMC_(PFX, _flag)(struct SNAME * _heap_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_INTERVALHEAP_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_); \ - static void CMC_(PFX, _impl_float_up_min)(struct SNAME * _heap_); \ - static void CMC_(PFX, _impl_float_down_max)(struct SNAME * _heap_); \ - static void CMC_(PFX, _impl_float_down_min)(struct SNAME * _heap_); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity == 0 || capacity == UINTMAX_MAX) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_heap_) \ - return NULL; \ - \ - capacity = (capacity + capacity % 2) / 2; \ - \ - _heap_->buffer = alloc->calloc(capacity, sizeof(V[2])); \ - \ - if (!_heap_->buffer) \ - { \ - alloc->free(_heap_); \ - return NULL; \ - } \ - \ - _heap_->capacity = capacity; \ - _heap_->size = 0; \ - _heap_->count = 0; \ - _heap_->flag = CMC_FLAG_OK; \ - _heap_->f_val = f_val; \ - _heap_->alloc = alloc; \ - _heap_->callbacks = NULL; \ - \ - return _heap_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity == 0 || capacity == UINTMAX_MAX) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_heap_) \ - return NULL; \ - \ - capacity = (capacity + capacity % 2) / 2; \ - \ - _heap_->buffer = alloc->calloc(capacity, sizeof(V[2])); \ - \ - if (!_heap_->buffer) \ - { \ - alloc->free(_heap_); \ - return NULL; \ - } \ - \ - _heap_->capacity = capacity; \ - _heap_->size = 0; \ - _heap_->count = 0; \ - _heap_->flag = CMC_FLAG_OK; \ - _heap_->f_val = f_val; \ - _heap_->alloc = alloc; \ - _heap_->callbacks = callbacks; \ - \ - return _heap_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _heap_) \ - { \ - if (_heap_->f_val->free) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - _heap_->f_val->free(_heap_->buffer[i / 2][i % 2]); \ - } \ - } \ - \ - memset(_heap_->buffer, 0, sizeof(V[2]) * _heap_->capacity); \ - \ - _heap_->size = 0; \ - _heap_->count = 0; \ - _heap_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _heap_) \ - { \ - if (_heap_->f_val->free) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - _heap_->f_val->free(_heap_->buffer[i / 2][i % 2]); \ - } \ - } \ - \ - _heap_->alloc->free(_heap_->buffer); \ - \ - _heap_->alloc->free(_heap_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _heap_->alloc = &cmc_alloc_node_default; \ - else \ - _heap_->alloc = alloc; \ - \ - _heap_->callbacks = callbacks; \ - \ - _heap_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \ - { \ - if (CMC_(PFX, _full)(_heap_)) \ - { \ - if (!CMC_(PFX, _resize)(_heap_, _heap_->capacity * 4)) \ - return false; \ - } \ - \ - if (_heap_->count % 2 == 0) \ - { \ - /* Occupying a new node */ \ - _heap_->buffer[_heap_->size][0] = value; \ - _heap_->buffer[_heap_->size][1] = (V){ 0 }; \ - \ - _heap_->size++; \ - } \ - else \ - { \ - V(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ - \ - /* Decide if the new element goes into the MinHeap or MaxHeap */ \ - if (_heap_->f_val->cmp((*node)[0], value) > 0) \ - { \ - /* Swap current value and add new element to the MinHeap */ \ - (*node)[1] = (*node)[0]; \ - (*node)[0] = value; \ - } \ - else \ - { \ - /* No need to swap and add the new element to the MaxHeap */ \ - (*node)[1] = value; \ - } \ - } \ - \ - _heap_->count++; \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->count > 2) \ - { \ - /* Determine wheather to do a MaxHeap insert or a MinHeap */ \ - /* insert. For any integer this index calculation results in */ \ - /* an even number representing the parent of the last value */ \ - V(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); \ - \ - if (_heap_->f_val->cmp((*parent)[0], value) > 0) \ - CMC_(PFX, _impl_float_up_min)(_heap_); \ - else if (_heap_->f_val->cmp((*parent)[1], value) < 0) \ - CMC_(PFX, _impl_float_up_max)(_heap_); \ - /* else no float up required */ \ - } \ - \ - if (_heap_->callbacks && _heap_->callbacks->create) \ - _heap_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove_max)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (_heap_->count == 1) \ - { \ - _heap_->buffer[0][0] = (V){ 0 }; \ - \ - _heap_->count--; \ - _heap_->size--; \ - \ - goto success; \ - } \ - \ - /* Swap the result with the last element in the MaxHeap and float */ \ - /* it down */ \ - V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ - \ - if (_heap_->count % 2 == 1) \ - { \ - /* Grab from MinHeap and discard last node */ \ - _heap_->buffer[0][1] = (*last_node)[0]; \ - \ - (*last_node)[0] = (V){ 0 }; \ - \ - _heap_->size--; \ - } \ - else \ - { \ - _heap_->buffer[0][1] = (*last_node)[1]; \ - \ - (*last_node)[1] = (V){ 0 }; \ - } \ - \ - _heap_->count--; \ - \ - /* FLoat Down on the MaxHeap */ \ - CMC_(PFX, _impl_float_down_max)(_heap_); \ - \ - success: \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->delete) \ - _heap_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove_min)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (_heap_->count == 1) \ - { \ - _heap_->buffer[0][0] = (V){ 0 }; \ - \ - _heap_->count--; \ - _heap_->size--; \ - \ - goto success; \ - } \ - \ - /* Swap the result with the last element in the MinHeap and float */ \ - /* it down */ \ - V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ - \ - _heap_->buffer[0][0] = (*last_node)[0]; \ - \ - if (_heap_->count % 2 == 1) \ - { \ - /* Discard last node */ \ - (*last_node)[0] = (V){ 0 }; \ - \ - _heap_->size--; \ - } \ - else \ - { \ - /* Place the MaxHeap value in the MinHeap value spot */ \ - (*last_node)[0] = (*last_node)[1]; \ - (*last_node)[1] = (V){ 0 }; \ - } \ - \ - _heap_->count--; \ - \ - /* FLoat Down on the MinHeap */ \ - CMC_(PFX, _impl_float_down_min)(_heap_); \ - \ - success: \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->delete) \ - _heap_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (_heap_->count == 1) \ - { \ - _heap_->buffer[0][0] = value; \ - } \ - else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0) \ - { \ - /* Corner case: we are updating the Max value but it is less */ \ - /* than the Min value */ \ - _heap_->buffer[0][1] = _heap_->buffer[0][0]; \ - _heap_->buffer[0][0] = value; \ - \ - CMC_(PFX, _impl_float_down_max)(_heap_); \ - } \ - else \ - { \ - /* Update Max element and float it down */ \ - _heap_->buffer[0][1] = value; \ - \ - CMC_(PFX, _impl_float_down_max)(_heap_); \ - } \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->update) \ - _heap_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (_heap_->count == 1) \ - { \ - _heap_->buffer[0][0] = value; \ - } \ - else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) \ - { \ +#define CMC_CMC_INTERVALHEAP_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_); \ + static void CMC_(PFX, _impl_float_up_min)(struct SNAME * _heap_); \ + static void CMC_(PFX, _impl_float_down_max)(struct SNAME * _heap_); \ + static void CMC_(PFX, _impl_float_down_min)(struct SNAME * _heap_); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity == 0 || capacity == UINTMAX_MAX) \ + return NULL; \ +\ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_heap_) \ + return NULL; \ +\ + capacity = (capacity + capacity % 2) / 2; \ +\ + _heap_->buffer = alloc->calloc(capacity, sizeof(V[2])); \ +\ + if (!_heap_->buffer) \ + { \ + alloc->free(_heap_); \ + return NULL; \ + } \ +\ + _heap_->capacity = capacity; \ + _heap_->size = 0; \ + _heap_->count = 0; \ + _heap_->flag = CMC_FLAG_OK; \ + _heap_->f_val = f_val; \ + _heap_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \ +\ + return _heap_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _heap_) \ + { \ + if (_heap_->f_val->free) \ + { \ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + _heap_->f_val->free(_heap_->buffer[i / 2][i % 2]); \ + } \ + } \ +\ + memset(_heap_->buffer, 0, sizeof(V[2]) * _heap_->capacity); \ +\ + _heap_->size = 0; \ + _heap_->count = 0; \ + _heap_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _heap_) \ + { \ + if (_heap_->f_val->free) \ + { \ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + _heap_->f_val->free(_heap_->buffer[i / 2][i % 2]); \ + } \ + } \ +\ + _heap_->alloc->free(_heap_->buffer); \ +\ + _heap_->alloc->free(_heap_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _heap_->alloc = &cmc_alloc_node_default; \ + else \ + _heap_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \ +\ + _heap_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \ + { \ + if (CMC_(PFX, _full)(_heap_)) \ + { \ + if (!CMC_(PFX, _resize)(_heap_, _heap_->capacity * 4)) \ + return false; \ + } \ +\ + if (_heap_->count % 2 == 0) \ + { \ + /* Occupying a new node */ \ + _heap_->buffer[_heap_->size][0] = value; \ + _heap_->buffer[_heap_->size][1] = (V){ 0 }; \ +\ + _heap_->size++; \ + } \ + else \ + { \ + V(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ +\ + /* Decide if the new element goes into the MinHeap or MaxHeap */ \ + if (_heap_->f_val->cmp((*node)[0], value) > 0) \ + { \ + /* Swap current value and add new element to the MinHeap */ \ + (*node)[1] = (*node)[0]; \ + (*node)[0] = value; \ + } \ + else \ + { \ + /* No need to swap and add the new element to the MaxHeap */ \ + (*node)[1] = value; \ + } \ + } \ +\ + _heap_->count++; \ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->count > 2) \ + { \ + /* Determine wheather to do a MaxHeap insert or a MinHeap */ \ + /* insert. For any integer this index calculation results in */ \ + /* an even number representing the parent of the last value */ \ + V(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); \ +\ + if (_heap_->f_val->cmp((*parent)[0], value) > 0) \ + CMC_(PFX, _impl_float_up_min)(_heap_); \ + else if (_heap_->f_val->cmp((*parent)[1], value) < 0) \ + CMC_(PFX, _impl_float_up_max)(_heap_); \ + /* else no float up required */ \ + } \ +\ + if (_heap_->callbacks && _heap_->callbacks->create) \ + _heap_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove_max)(struct SNAME * _heap_) \ + { \ + if (CMC_(PFX, _empty)(_heap_)) \ + { \ + _heap_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + if (_heap_->count == 1) \ + { \ + _heap_->buffer[0][0] = (V){ 0 }; \ +\ + _heap_->count--; \ + _heap_->size--; \ +\ + goto success; \ + } \ +\ + /* Swap the result with the last element in the MaxHeap and float */ \ + /* it down */ \ + V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ +\ + if (_heap_->count % 2 == 1) \ + { \ + /* Grab from MinHeap and discard last node */ \ + _heap_->buffer[0][1] = (*last_node)[0]; \ +\ + (*last_node)[0] = (V){ 0 }; \ +\ + _heap_->size--; \ + } \ + else \ + { \ + _heap_->buffer[0][1] = (*last_node)[1]; \ +\ + (*last_node)[1] = (V){ 0 }; \ + } \ +\ + _heap_->count--; \ +\ + /* FLoat Down on the MaxHeap */ \ + CMC_(PFX, _impl_float_down_max)(_heap_); \ +\ + success: \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->delete) \ + _heap_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove_min)(struct SNAME * _heap_) \ + { \ + if (CMC_(PFX, _empty)(_heap_)) \ + { \ + _heap_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + if (_heap_->count == 1) \ + { \ + _heap_->buffer[0][0] = (V){ 0 }; \ +\ + _heap_->count--; \ + _heap_->size--; \ +\ + goto success; \ + } \ +\ + /* Swap the result with the last element in the MinHeap and float */ \ + /* it down */ \ + V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ +\ + _heap_->buffer[0][0] = (*last_node)[0]; \ +\ + if (_heap_->count % 2 == 1) \ + { \ + /* Discard last node */ \ + (*last_node)[0] = (V){ 0 }; \ +\ + _heap_->size--; \ + } \ + else \ + { \ + /* Place the MaxHeap value in the MinHeap value spot */ \ + (*last_node)[0] = (*last_node)[1]; \ + (*last_node)[1] = (V){ 0 }; \ + } \ +\ + _heap_->count--; \ +\ + /* FLoat Down on the MinHeap */ \ + CMC_(PFX, _impl_float_down_min)(_heap_); \ +\ + success: \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->delete) \ + _heap_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value) \ + { \ + if (CMC_(PFX, _empty)(_heap_)) \ + { \ + _heap_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + if (_heap_->count == 1) \ + { \ + _heap_->buffer[0][0] = value; \ + } \ + else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0) \ + { \ + /* Corner case: we are updating the Max value but it is less */ \ + /* than the Min value */ \ + _heap_->buffer[0][1] = _heap_->buffer[0][0]; \ + _heap_->buffer[0][0] = value; \ +\ + CMC_(PFX, _impl_float_down_max)(_heap_); \ + } \ + else \ + { \ + /* Update Max element and float it down */ \ + _heap_->buffer[0][1] = value; \ +\ + CMC_(PFX, _impl_float_down_max)(_heap_); \ + } \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->update) \ + _heap_->callbacks->update(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value) \ + { \ + if (CMC_(PFX, _empty)(_heap_)) \ + { \ + _heap_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + if (_heap_->count == 1) \ + { \ + _heap_->buffer[0][0] = value; \ + } \ + else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) \ + { \ /* Corner case: we are updating the Min value but it is greater */ \ - /* than the Max value. */ \ - _heap_->buffer[0][0] = _heap_->buffer[0][1]; \ - _heap_->buffer[0][1] = value; \ - \ - CMC_(PFX, _impl_float_down_min)(_heap_); \ - } \ - else \ - { \ - /* Update Min element and float it down */ \ - _heap_->buffer[0][0] = value; \ - \ - CMC_(PFX, _impl_float_down_min)(_heap_); \ - } \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->update) \ - _heap_->callbacks->update(); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _max)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ - \ - /* If there is only one element, then the maximum element is the */ \ - /* same as the one in the MinHeap */ \ - if (_heap_->count == 1) \ - return _heap_->buffer[0][0]; \ - \ - return _heap_->buffer[0][1]; \ - } \ - \ - V CMC_(PFX, _min)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ - \ - return _heap_->buffer[0][0]; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \ - { \ - _heap_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ - \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_) \ - { \ - return _heap_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _heap_) \ - { \ - /* The heap is full if all nodes are completely filled */ \ - return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_) \ - { \ - return _heap_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \ - { \ - return _heap_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _heap_) \ - { \ - return _heap_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \ - { \ - if (_heap_->capacity == capacity) \ - goto success; \ - \ - if (capacity < _heap_->count) \ - { \ - _heap_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - /* Prevent overflow */ \ - if (capacity == UINTMAX_MAX) \ - { \ - _heap_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ - \ - capacity += capacity % 2; \ - \ - V(*new_buffer) \ - [2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(V[2]) * capacity); \ - \ - if (!new_buffer) \ - { \ - _heap_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - if (capacity > _heap_->capacity) \ - { \ - memset(new_buffer + _heap_->capacity, 0, \ - sizeof(V[2]) * (capacity - _heap_->capacity)); \ - } \ - \ - _heap_->buffer = new_buffer; \ - _heap_->capacity = capacity; \ - \ - success: \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - if (_heap_->callbacks && _heap_->callbacks->resize) \ - _heap_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \ - { \ - struct SNAME *result = _heap_->alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!result) \ - { \ - _heap_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - memcpy(result, _heap_, sizeof(struct SNAME)); \ - \ - result->buffer = \ - _heap_->alloc->malloc(sizeof(V[2]) * _heap_->capacity); \ - \ - if (!result->buffer) \ - { \ - _heap_->alloc->free(result); \ - _heap_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - if (_heap_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - result->buffer[i / 2][i % 2] = \ - _heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]); \ - } \ - else \ - memcpy(result->buffer, _heap_->buffer, \ - sizeof(V[2]) * _heap_->capacity); \ - \ - result->capacity = _heap_->capacity; \ - result->size = _heap_->size; \ - result->count = _heap_->count; \ - result->flag = CMC_FLAG_OK; \ - result->f_val = _heap_->f_val; \ - result->alloc = _heap_->alloc; \ - result->callbacks = _heap_->callbacks; \ - \ - _heap_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \ - { \ - _heap1_->flag = CMC_FLAG_OK; \ - _heap2_->flag = CMC_FLAG_OK; \ - \ - if (_heap1_->count != _heap2_->count) \ - return false; \ - \ - for (size_t i = 0; i < _heap1_->count; i++) \ - { \ - V value1 = _heap1_->buffer[i / 2][i % 2]; \ - V value2 = _heap2_->buffer[i / 2][i % 2]; \ - \ - if (_heap1_->f_val->cmp(value1, value2) != 0) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_) \ - { \ - size_t index = _heap_->size - 1; \ - \ - V(*curr_node)[2] = &(_heap_->buffer[index]); \ - \ - /* FLoat Up on the MaxHeap */ \ - while (index > 0) \ - { \ - /* Parent index */ \ - size_t P_index = (index - 1) / 2; \ - \ - V(*parent)[2] = &(_heap_->buffer[P_index]); \ - \ - if (index == _heap_->size - 1 && _heap_->count % 2 != 0) \ - { \ - /* In this case, the current node has no MaxHeap value so */ \ - /* we instead compare with the MinHeap value */ \ - if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0) \ - break; \ - \ - /* Since the comparison above passed now we need to swap */ \ - /* the current node with the parent but it will have to be */ \ - /* done with the node's MinHeap value since the MaxHeap */ \ - /* value doesn't exist */ \ - V tmp = (*curr_node)[0]; \ - (*curr_node)[0] = (*parent)[1]; \ - (*parent)[1] = tmp; \ - } \ - else \ - { \ - /* Usual case, just compare both MaxHeap values */ \ - if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0) \ - break; \ - \ - /* Swap with parent and repeat */ \ - V tmp = (*curr_node)[1]; \ - (*curr_node)[1] = (*parent)[1]; \ - (*parent)[1] = tmp; \ - } \ - \ - /* Update indexe and node */ \ - index = P_index; \ - curr_node = parent; \ - } \ - } \ - \ - static void CMC_(PFX, _impl_float_up_min)(struct SNAME * _heap_) \ - { \ - size_t index = _heap_->size - 1; \ - \ - V(*curr_node)[2] = &(_heap_->buffer[index]); \ - \ - /* FLoat Up on the MinHeap */ \ - while (index > 0) \ - { \ - /* Parent index */ \ - size_t P_index = (index - 1) / 2; \ - \ - V(*parent)[2] = &(_heap_->buffer[P_index]); \ - \ - if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) \ - break; \ - \ - /* Swap with parent and repeat */ \ - V tmp = (*curr_node)[0]; \ - (*curr_node)[0] = (*parent)[0]; \ - (*parent)[0] = tmp; \ - \ - /* Update indexe and node */ \ - index = P_index; \ - curr_node = parent; \ - } \ - } \ - \ - static void CMC_(PFX, _impl_float_down_max)(struct SNAME * _heap_) \ - { \ - /* Floats Down from the MinHeap */ \ - size_t index = 0; \ - \ - V(*curr_node)[2] = &(_heap_->buffer[index]); \ - \ - while (true) \ - { \ - /* If there are no children it is done */ \ - if (2 * index + 1 >= _heap_->size) \ - break; \ - \ - /* Child index to be compared with current value */ \ - size_t child; \ - size_t L_index = index * 2 + 1; \ - size_t R_index = index * 2 + 2; \ - \ - /* If there are two children, pick the smallest one */ \ - if (R_index < _heap_->size) \ - { \ - V(*L)[2] = &(_heap_->buffer[L_index]); \ - V(*R)[2] = &(_heap_->buffer[R_index]); \ - \ - /* If the right child is the last node and there is no */ \ - /* MaxHeap value */ \ - /* then do the comparison with the MinHeap value */ \ - if (R_index == _heap_->size - 1 && _heap_->count % 2 != 0) \ - child = _heap_->f_val->cmp((*L)[1], (*R)[0]) > 0 \ - ? L_index \ - : R_index; \ - else \ - child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 \ - ? L_index \ - : R_index; \ - } \ - /* Pick the only one available */ \ - else \ - child = L_index; \ - \ - V(*child_node)[2] = &(_heap_->buffer[child]); \ - \ - /* Again, check if the child node is the last one and has no */ \ - /* MaxHeap value */ \ - if (child == _heap_->size - 1 && _heap_->count % 2 != 0) \ - { \ - /* Odd case, compare with MinHeap value */ \ - /* If current value is not less than the child node's */ \ - /* value it is done */ \ - if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= \ - 0) \ - break; \ - \ - /* Otherwise swap and continue */ \ - V tmp = (*child_node)[0]; \ - (*child_node)[0] = (*curr_node)[1]; \ - (*curr_node)[1] = tmp; \ - } \ - else \ - { \ - /* If current value is not less than the child node's */ \ - /* value it is done */ \ - if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= \ - 0) \ - break; \ - \ - /* Otherwise swap and continue */ \ - V tmp = (*child_node)[1]; \ - (*child_node)[1] = (*curr_node)[1]; \ - (*curr_node)[1] = tmp; \ - \ - /* Check if the MinHeap and MaxHeap values need to be */ \ - /* swapped */ \ - if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > \ - 0) \ - { \ - /* Swap because the MinHeap value is greater than the */ \ - /* MaxHeap value */ \ - tmp = (*child_node)[0]; \ - (*child_node)[0] = (*child_node)[1]; \ - (*child_node)[1] = tmp; \ - } \ - } \ - \ - /* Update index and node */ \ - index = child; \ - curr_node = child_node; \ - } \ - } \ - \ - static void CMC_(PFX, _impl_float_down_min)(struct SNAME * _heap_) \ - { \ - /* Floats Down from the MinHeap */ \ - size_t index = 0; \ - \ - V(*curr_node)[2] = &(_heap_->buffer[index]); \ - \ - while (true) \ - { \ - /* If there are no children it is done */ \ - if (2 * index + 1 >= _heap_->size) \ - break; \ - \ - /* Child index to be compared with current value */ \ - size_t child; \ - size_t L_index = index * 2 + 1; \ - size_t R_index = index * 2 + 2; \ - \ - /* If there are two children, pick the smallest one */ \ - if (R_index < _heap_->size) \ - { \ - V(*L)[2] = &(_heap_->buffer[L_index]); \ - V(*R)[2] = &(_heap_->buffer[R_index]); \ - \ - child = _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index \ - : R_index; \ - } \ - /* Pick the only one available */ \ - else \ - child = L_index; \ - \ - V(*child_node)[2] = &(_heap_->buffer[child]); \ - \ - /* If current value is smaller than the child node's value, it */ \ - /* is done */ \ - if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) \ - break; \ - \ - /* Otherwise swap and continue */ \ - V tmp = (*child_node)[0]; \ - (*child_node)[0] = (*curr_node)[0]; \ - (*curr_node)[0] = tmp; \ - \ - /* If the child node is the last node check if the MinHeap and */ \ - /* MaxHeap values need to be swapped */ \ - if (child != _heap_->size - 1 || _heap_->count % 2 == 0) \ - { \ - if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > \ - 0) \ - { \ - /* Swap because the MinHeap value is greater than the */ \ - /* MaxHeap value */ \ - tmp = (*child_node)[0]; \ - (*child_node)[0] = (*child_node)[1]; \ - (*child_node)[1] = tmp; \ - } \ - } \ - \ - /* Update index and node */ \ - index = child; \ - curr_node = child_node; \ - } \ + /* than the Max value. */ \ + _heap_->buffer[0][0] = _heap_->buffer[0][1]; \ + _heap_->buffer[0][1] = value; \ +\ + CMC_(PFX, _impl_float_down_min)(_heap_); \ + } \ + else \ + { \ + /* Update Min element and float it down */ \ + _heap_->buffer[0][0] = value; \ +\ + CMC_(PFX, _impl_float_down_min)(_heap_); \ + } \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->update) \ + _heap_->callbacks->update(); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _max)(struct SNAME * _heap_) \ + { \ + if (CMC_(PFX, _empty)(_heap_)) \ + { \ + _heap_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->read) \ + _heap_->callbacks->read(); \ +\ + /* If there is only one element, then the maximum element is the */ \ + /* same as the one in the MinHeap */ \ + if (_heap_->count == 1) \ + return _heap_->buffer[0][0]; \ +\ + return _heap_->buffer[0][1]; \ + } \ +\ + V CMC_(PFX, _min)(struct SNAME * _heap_) \ + { \ + if (CMC_(PFX, _empty)(_heap_)) \ + { \ + _heap_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->read) \ + _heap_->callbacks->read(); \ +\ + return _heap_->buffer[0][0]; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \ + { \ + _heap_->flag = CMC_FLAG_OK; \ +\ + bool result = false; \ +\ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0) \ + { \ + result = true; \ + break; \ + } \ + } \ +\ + if (_heap_->callbacks && _heap_->callbacks->read) \ + _heap_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _heap_) \ + { \ + return _heap_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _heap_) \ + { \ + /* The heap is full if all nodes are completely filled */ \ + return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _heap_) \ + { \ + return _heap_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \ + { \ + return _heap_->capacity; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _heap_) \ + { \ + return _heap_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \ + { \ + if (_heap_->capacity == capacity) \ + goto success; \ +\ + if (capacity < _heap_->count) \ + { \ + _heap_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + /* Prevent overflow */ \ + if (capacity == UINTMAX_MAX) \ + { \ + _heap_->flag = CMC_FLAG_ERROR; \ + return false; \ + } \ +\ + capacity += capacity % 2; \ +\ + V(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(V[2]) * capacity); \ +\ + if (!new_buffer) \ + { \ + _heap_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + if (capacity > _heap_->capacity) \ + { \ + memset(new_buffer + _heap_->capacity, 0, sizeof(V[2]) * (capacity - _heap_->capacity)); \ + } \ +\ + _heap_->buffer = new_buffer; \ + _heap_->capacity = capacity; \ +\ + success: \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + if (_heap_->callbacks && _heap_->callbacks->resize) \ + _heap_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \ + { \ + struct SNAME *result = _heap_->alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!result) \ + { \ + _heap_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + memcpy(result, _heap_, sizeof(struct SNAME)); \ +\ + result->buffer = _heap_->alloc->malloc(sizeof(V[2]) * _heap_->capacity); \ +\ + if (!result->buffer) \ + { \ + _heap_->alloc->free(result); \ + _heap_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + if (_heap_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _heap_->count; i++) \ + result->buffer[i / 2][i % 2] = _heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]); \ + } \ + else \ + memcpy(result->buffer, _heap_->buffer, sizeof(V[2]) * _heap_->capacity); \ +\ + result->capacity = _heap_->capacity; \ + result->size = _heap_->size; \ + result->count = _heap_->count; \ + result->flag = CMC_FLAG_OK; \ + result->f_val = _heap_->f_val; \ + result->alloc = _heap_->alloc; \ + CMC_CALLBACKS_ASSIGN(result, _heap_->callbacks); \ +\ + _heap_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \ + { \ + _heap1_->flag = CMC_FLAG_OK; \ + _heap2_->flag = CMC_FLAG_OK; \ +\ + if (_heap1_->count != _heap2_->count) \ + return false; \ +\ + for (size_t i = 0; i < _heap1_->count; i++) \ + { \ + V value1 = _heap1_->buffer[i / 2][i % 2]; \ + V value2 = _heap2_->buffer[i / 2][i % 2]; \ +\ + if (_heap1_->f_val->cmp(value1, value2) != 0) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_) \ + { \ + size_t index = _heap_->size - 1; \ +\ + V(*curr_node)[2] = &(_heap_->buffer[index]); \ +\ + /* FLoat Up on the MaxHeap */ \ + while (index > 0) \ + { \ + /* Parent index */ \ + size_t P_index = (index - 1) / 2; \ +\ + V(*parent)[2] = &(_heap_->buffer[P_index]); \ +\ + if (index == _heap_->size - 1 && _heap_->count % 2 != 0) \ + { \ + /* In this case, the current node has no MaxHeap value so */ \ + /* we instead compare with the MinHeap value */ \ + if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0) \ + break; \ +\ + /* Since the comparison above passed now we need to swap */ \ + /* the current node with the parent but it will have to be */ \ + /* done with the node's MinHeap value since the MaxHeap */ \ + /* value doesn't exist */ \ + V tmp = (*curr_node)[0]; \ + (*curr_node)[0] = (*parent)[1]; \ + (*parent)[1] = tmp; \ + } \ + else \ + { \ + /* Usual case, just compare both MaxHeap values */ \ + if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0) \ + break; \ +\ + /* Swap with parent and repeat */ \ + V tmp = (*curr_node)[1]; \ + (*curr_node)[1] = (*parent)[1]; \ + (*parent)[1] = tmp; \ + } \ +\ + /* Update indexe and node */ \ + index = P_index; \ + curr_node = parent; \ + } \ + } \ +\ + static void CMC_(PFX, _impl_float_up_min)(struct SNAME * _heap_) \ + { \ + size_t index = _heap_->size - 1; \ +\ + V(*curr_node)[2] = &(_heap_->buffer[index]); \ +\ + /* FLoat Up on the MinHeap */ \ + while (index > 0) \ + { \ + /* Parent index */ \ + size_t P_index = (index - 1) / 2; \ +\ + V(*parent)[2] = &(_heap_->buffer[P_index]); \ +\ + if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) \ + break; \ +\ + /* Swap with parent and repeat */ \ + V tmp = (*curr_node)[0]; \ + (*curr_node)[0] = (*parent)[0]; \ + (*parent)[0] = tmp; \ +\ + /* Update indexe and node */ \ + index = P_index; \ + curr_node = parent; \ + } \ + } \ +\ + static void CMC_(PFX, _impl_float_down_max)(struct SNAME * _heap_) \ + { \ + /* Floats Down from the MinHeap */ \ + size_t index = 0; \ +\ + V(*curr_node)[2] = &(_heap_->buffer[index]); \ +\ + while (true) \ + { \ + /* If there are no children it is done */ \ + if (2 * index + 1 >= _heap_->size) \ + break; \ +\ + /* Child index to be compared with current value */ \ + size_t child; \ + size_t L_index = index * 2 + 1; \ + size_t R_index = index * 2 + 2; \ +\ + /* If there are two children, pick the smallest one */ \ + if (R_index < _heap_->size) \ + { \ + V(*L)[2] = &(_heap_->buffer[L_index]); \ + V(*R)[2] = &(_heap_->buffer[R_index]); \ +\ + /* If the right child is the last node and there is no */ \ + /* MaxHeap value */ \ + /* then do the comparison with the MinHeap value */ \ + if (R_index == _heap_->size - 1 && _heap_->count % 2 != 0) \ + child = _heap_->f_val->cmp((*L)[1], (*R)[0]) > 0 ? L_index : R_index; \ + else \ + child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index; \ + } \ + /* Pick the only one available */ \ + else \ + child = L_index; \ +\ + V(*child_node)[2] = &(_heap_->buffer[child]); \ +\ + /* Again, check if the child node is the last one and has no */ \ + /* MaxHeap value */ \ + if (child == _heap_->size - 1 && _heap_->count % 2 != 0) \ + { \ + /* Odd case, compare with MinHeap value */ \ + /* If current value is not less than the child node's */ \ + /* value it is done */ \ + if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0) \ + break; \ +\ + /* Otherwise swap and continue */ \ + V tmp = (*child_node)[0]; \ + (*child_node)[0] = (*curr_node)[1]; \ + (*curr_node)[1] = tmp; \ + } \ + else \ + { \ + /* If current value is not less than the child node's */ \ + /* value it is done */ \ + if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0) \ + break; \ +\ + /* Otherwise swap and continue */ \ + V tmp = (*child_node)[1]; \ + (*child_node)[1] = (*curr_node)[1]; \ + (*curr_node)[1] = tmp; \ +\ + /* Check if the MinHeap and MaxHeap values need to be */ \ + /* swapped */ \ + if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) \ + { \ + /* Swap because the MinHeap value is greater than the */ \ + /* MaxHeap value */ \ + tmp = (*child_node)[0]; \ + (*child_node)[0] = (*child_node)[1]; \ + (*child_node)[1] = tmp; \ + } \ + } \ +\ + /* Update index and node */ \ + index = child; \ + curr_node = child_node; \ + } \ + } \ +\ + static void CMC_(PFX, _impl_float_down_min)(struct SNAME * _heap_) \ + { \ + /* Floats Down from the MinHeap */ \ + size_t index = 0; \ +\ + V(*curr_node)[2] = &(_heap_->buffer[index]); \ +\ + while (true) \ + { \ + /* If there are no children it is done */ \ + if (2 * index + 1 >= _heap_->size) \ + break; \ +\ + /* Child index to be compared with current value */ \ + size_t child; \ + size_t L_index = index * 2 + 1; \ + size_t R_index = index * 2 + 2; \ +\ + /* If there are two children, pick the smallest one */ \ + if (R_index < _heap_->size) \ + { \ + V(*L)[2] = &(_heap_->buffer[L_index]); \ + V(*R)[2] = &(_heap_->buffer[R_index]); \ +\ + child = _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index; \ + } \ + /* Pick the only one available */ \ + else \ + child = L_index; \ +\ + V(*child_node)[2] = &(_heap_->buffer[child]); \ +\ + /* If current value is smaller than the child node's value, it */ \ + /* is done */ \ + if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) \ + break; \ +\ + /* Otherwise swap and continue */ \ + V tmp = (*child_node)[0]; \ + (*child_node)[0] = (*curr_node)[0]; \ + (*curr_node)[0] = tmp; \ +\ + /* If the child node is the last node check if the MinHeap and */ \ + /* MaxHeap values need to be swapped */ \ + if (child != _heap_->size - 1 || _heap_->count % 2 == 0) \ + { \ + if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) \ + { \ + /* Swap because the MinHeap value is greater than the */ \ + /* MaxHeap value */ \ + tmp = (*child_node)[0]; \ + (*child_node)[0] = (*child_node)[1]; \ + (*child_node)[1] = tmp; \ + } \ + } \ +\ + /* Update index and node */ \ + index = child; \ + curr_node = child_node; \ + } \ } #endif /* CMC_CMC_INTERVALHEAP_H */ diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index b332033..044a737 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -36,602 +36,571 @@ /** * Core LinkedList implementation */ -#define CMC_CMC_LINKEDLIST_CORE(PARAMS) \ +#define CMC_CMC_LINKEDLIST_CORE(PARAMS) \ CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) \ CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) #define CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_CMC_LINKEDLIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_CMC_LINKEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Linked List Structure */ \ - struct SNAME \ - { \ - /* First node in the list */ \ - struct CMC_DEF_NODE(SNAME) * head; \ - \ - /* Last node in the list */ \ - struct CMC_DEF_NODE(SNAME) * tail; \ - \ - /* Current amount of elements in the list */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Doubly-linked list node */ \ - struct CMC_DEF_NODE(SNAME) \ - { \ - /* Node's value */ \ - V value; \ - \ - /* Pointer to the next node on the linked list */ \ - struct CMC_DEF_NODE(SNAME) * next; \ - \ - /* Pointer to the previous node on the linked list */ \ - struct CMC_DEF_NODE(SNAME) * prev; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ - V CMC_(PFX, _back)(struct SNAME * _list_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ +#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* Linked List Structure */ \ + struct SNAME \ + { \ + /* First node in the list */ \ + struct CMC_DEF_NODE(SNAME) * head; \ +\ + /* Last node in the list */ \ + struct CMC_DEF_NODE(SNAME) * tail; \ +\ + /* Current amount of elements in the list */ \ + size_t count; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Doubly-linked list node */ \ + struct CMC_DEF_NODE(SNAME) \ + { \ + /* Node's value */ \ + V value; \ +\ + /* Pointer to the next node on the linked list */ \ + struct CMC_DEF_NODE(SNAME) * next; \ +\ + /* Pointer to the previous node on the linked list */ \ + struct CMC_DEF_NODE(SNAME) * prev; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ + V CMC_(PFX, _back)(struct SNAME * _list_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - if (!f_val) \ - return NULL; \ - \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = NULL; \ - \ - return _list_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = callbacks; \ - \ - return _list_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (_list_->head != NULL) \ - { \ - _list_->head = _list_->head->next; \ - \ - if (_list_->f_val->free) \ - { \ - _list_->f_val->free(scan->value); \ - } \ - \ - _list_->alloc->free(scan); \ - \ - scan = _list_->head; \ - } \ - \ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - CMC_(PFX, _clear)(_list_); \ - \ - _list_->alloc->free(_list_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _list_->alloc = &cmc_alloc_node_default; \ - else \ - _list_->alloc = alloc; \ - \ - _list_->callbacks = callbacks; \ - \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->head = _node_; \ - _list_->tail = _node_; \ - } \ - else \ - { \ - _node_->next = _list_->head; \ - _list_->head->prev = _node_; \ - _list_->head = _node_; \ - } \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ - { \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - { \ - return CMC_(PFX, _push_front)(_list_, value); \ - } \ - else if (index == _list_->count) \ - { \ - return CMC_(PFX, _push_back)(_list_, value); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index - 1); \ - \ - _node_->next = scan->next; \ - _node_->prev = scan; \ - _node_->next->prev = _node_; \ - _node_->prev->next = _node_; \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _new_node)(_list_, value); \ - \ - if (!_node_) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->head = _node_; \ - _list_->tail = _node_; \ - } \ - else \ - { \ - _node_->prev = _list_->tail; \ - _list_->tail->next = _node_; \ - _list_->tail = _node_; \ - } \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \ - _list_->head = _list_->head->next; \ - \ - _list_->alloc->free(_node_); \ - \ - if (_list_->head == NULL) \ - _list_->tail = NULL; \ - else \ - _list_->head->prev = NULL; \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - { \ - return CMC_(PFX, _pop_front)(_list_); \ - } \ - else if (index == _list_->count - 1) \ - { \ - return CMC_(PFX, _pop_back)(_list_); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (!_node_) \ - return false; \ - \ - _node_->next->prev = _node_->prev; \ - _node_->prev->next = _node_->next; \ - \ - _list_->alloc->free(_node_); \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \ - _list_->tail = _list_->tail->prev; \ - \ - _list_->alloc->free(_node_); \ - \ - if (_list_->tail == NULL) \ - _list_->head = NULL; \ - else \ - _list_->tail->next = NULL; \ - \ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->head->value; \ - } \ - \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (scan == NULL) \ - return (V){ 0 }; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return scan->value; \ - } \ - \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = \ - CMC_(PFX, _get_node)(_list_, index); \ - \ - if (scan == NULL) \ - return NULL; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return &(scan->value); \ - } \ - \ - V CMC_(PFX, _back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->tail->value; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - if (_list_->f_val->cmp(scan->value, value) == 0) \ - { \ - result = true; \ - break; \ - } \ - \ - scan = scan->next; \ - } \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _list_->f_val, _list_->alloc, _list_->callbacks); \ - \ - if (!result) \ - return NULL; \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - /* This allocation should never fail since it might not be */ \ - /* possible to recover from it. That is why it isn't checked */ \ - struct CMC_DEF_NODE(SNAME) * new_node; \ - \ - if (_list_->f_val->cpy) \ - new_node = CMC_(PFX, _new_node)( \ - _list_, _list_->f_val->cpy(scan->value)); \ - else \ - new_node = CMC_(PFX, _new_node)(_list_, scan->value); \ - \ - if (!result->head) \ - { \ - result->head = new_node; \ - result->tail = new_node; \ - } \ - else \ - { \ - new_node->prev = result->tail; \ - result->tail->next = new_node; \ - result->tail = new_node; \ - } \ - \ - scan = scan->next; \ - } \ - \ - result->count = _list_->count; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - _list1_->flag = CMC_FLAG_OK; \ - _list2_->flag = CMC_FLAG_OK; \ - \ - if (_list1_->count != _list2_->count) \ - return false; \ - \ - struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \ - struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \ - \ - while (scan1 != NULL && scan2 != NULL) \ - { \ - if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \ - return false; \ - \ - scan1 = scan1->next; \ - scan2 = scan2->next; \ - } \ - \ - return true; \ +#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + /* None */ \ +\ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_list_) \ + return NULL; \ +\ + _list_->count = 0; \ + _list_->head = NULL; \ + _list_->tail = NULL; \ + _list_->flag = CMC_FLAG_OK; \ + _list_->f_val = f_val; \ + _list_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ +\ + return _list_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ +\ + while (_list_->head != NULL) \ + { \ + _list_->head = _list_->head->next; \ +\ + if (_list_->f_val->free) \ + { \ + _list_->f_val->free(scan->value); \ + } \ +\ + _list_->alloc->free(scan); \ +\ + scan = _list_->head; \ + } \ +\ + _list_->count = 0; \ + _list_->head = NULL; \ + _list_->tail = NULL; \ + _list_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _list_) \ + { \ + CMC_(PFX, _clear)(_list_); \ +\ + _list_->alloc->free(_list_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _list_->alloc = &cmc_alloc_node_default; \ + else \ + _list_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ +\ + _list_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \ +\ + if (!_node_) \ + return false; \ +\ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->head = _node_; \ + _list_->tail = _node_; \ + } \ + else \ + { \ + _node_->next = _list_->head; \ + _list_->head->prev = _node_; \ + _list_->head = _node_; \ + } \ +\ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ + { \ + if (index > _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ +\ + if (index == 0) \ + { \ + return CMC_(PFX, _push_front)(_list_, value); \ + } \ + else if (index == _list_->count) \ + { \ + return CMC_(PFX, _push_back)(_list_, value); \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \ +\ + if (!_node_) \ + return false; \ +\ + struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index - 1); \ +\ + _node_->next = scan->next; \ + _node_->prev = scan; \ + _node_->next->prev = _node_; \ + _node_->prev->next = _node_; \ +\ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \ +\ + if (!_node_) \ + return false; \ +\ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->head = _node_; \ + _list_->tail = _node_; \ + } \ + else \ + { \ + _node_->prev = _list_->tail; \ + _list_->tail->next = _node_; \ + _list_->tail = _node_; \ + } \ +\ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \ + _list_->head = _list_->head->next; \ +\ + _list_->alloc->free(_node_); \ +\ + if (_list_->head == NULL) \ + _list_->tail = NULL; \ + else \ + _list_->head->prev = NULL; \ +\ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ +\ + if (index == 0) \ + { \ + return CMC_(PFX, _pop_front)(_list_); \ + } \ + else if (index == _list_->count - 1) \ + { \ + return CMC_(PFX, _pop_back)(_list_); \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _get_node)(_list_, index); \ +\ + if (!_node_) \ + return false; \ +\ + _node_->next->prev = _node_->prev; \ + _node_->prev->next = _node_->next; \ +\ + _list_->alloc->free(_node_); \ +\ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \ + _list_->tail = _list_->tail->prev; \ +\ + _list_->alloc->free(_node_); \ +\ + if (_list_->tail == NULL) \ + _list_->head = NULL; \ + else \ + _list_->tail->next = NULL; \ +\ + _list_->count--; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _front)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return _list_->head->value; \ + } \ +\ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return (V){ 0 }; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index); \ +\ + if (scan == NULL) \ + return (V){ 0 }; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return scan->value; \ + } \ +\ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return NULL; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index); \ +\ + if (scan == NULL) \ + return NULL; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return &(scan->value); \ + } \ +\ + V CMC_(PFX, _back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return _list_->tail->value; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ + { \ + _list_->flag = CMC_FLAG_OK; \ +\ + bool result = false; \ +\ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ +\ + while (scan != NULL) \ + { \ + if (_list_->f_val->cmp(scan->value, value) == 0) \ + { \ + result = true; \ + break; \ + } \ +\ + scan = scan->next; \ + } \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ + { \ + return _list_->count == 0; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _list_) \ + { \ + return _list_->count; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _list_) \ + { \ + return _list_->flag; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)(_list_->f_val, _list_->alloc, NULL); \ +\ + if (!result) \ + return NULL; \ +\ + CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \ +\ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ +\ + while (scan != NULL) \ + { \ + /* This allocation should never fail since it might not be */ \ + /* possible to recover from it. That is why it isn't checked */ \ + struct CMC_DEF_NODE(SNAME) * new_node; \ +\ + if (_list_->f_val->cpy) \ + new_node = CMC_(PFX, _new_node)(_list_, _list_->f_val->cpy(scan->value)); \ + else \ + new_node = CMC_(PFX, _new_node)(_list_, scan->value); \ +\ + if (!result->head) \ + { \ + result->head = new_node; \ + result->tail = new_node; \ + } \ + else \ + { \ + new_node->prev = result->tail; \ + result->tail->next = new_node; \ + result->tail = new_node; \ + } \ +\ + scan = scan->next; \ + } \ +\ + result->count = _list_->count; \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ + { \ + _list1_->flag = CMC_FLAG_OK; \ + _list2_->flag = CMC_FLAG_OK; \ +\ + if (_list1_->count != _list2_->count) \ + return false; \ +\ + struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \ + struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \ +\ + while (scan1 != NULL && scan2 != NULL) \ + { \ + if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \ + return false; \ +\ + scan1 = scan1->next; \ + scan2 = scan2->next; \ + } \ +\ + return true; \ } #endif /* CMC_CMC_LINKEDLIST_H */ diff --git a/src/cmc/list.h b/src/cmc/list.h index 1353481..5ba990a 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -51,593 +51,552 @@ /** * Core List implementation */ -#define CMC_CMC_LIST_CORE(PARAMS) \ +#define CMC_CMC_LIST_CORE(PARAMS) \ CMC_CMC_LIST_CORE_HEADER(PARAMS) \ CMC_CMC_LIST_CORE_SOURCE(PARAMS) -#define CMC_CMC_LIST_CORE_HEADER(PARAMS) \ - CMC_CMC_LIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_LIST_CORE_HEADER(PARAMS) \ + CMC_CMC_LIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_LIST_CORE_SOURCE(PARAMS) \ - CMC_CMC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_LIST_CORE_SOURCE(PARAMS) \ + CMC_CMC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ +#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* List Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ +\ + /* Current array capacity */ \ + size_t capacity; \ +\ + /* Current amount of elements */ \ + size_t count; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ - V CMC_(PFX, _back)(struct SNAME * _list_); \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ - bool from_start); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - bool CMC_(PFX, _full)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ + /* Element Access */ \ + V CMC_(PFX, _front)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ + V CMC_(PFX, _back)(struct SNAME * _list_); \ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + bool CMC_(PFX, _full)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_LIST_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity < 1) \ - return NULL; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_list_->buffer) \ - { \ - alloc->free(_list_); \ - return NULL; \ - } \ - \ - _list_->capacity = capacity; \ - _list_->count = 0; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = NULL; \ - \ - return _list_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_list_->buffer) \ - { \ - alloc->free(_list_); \ - return NULL; \ - } \ - \ - _list_->capacity = capacity; \ - _list_->count = 0; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = callbacks; \ - \ - return _list_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ - \ - memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ - \ - _list_->count = 0; \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ - \ - _list_->alloc->free(_list_->buffer); \ - _list_->alloc->free(_list_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _list_->alloc = &cmc_alloc_node_default; \ - else \ - _list_->alloc = alloc; \ - \ - _list_->callbacks = callbacks; \ - \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _full)(_list_)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ - return false; \ - } \ - \ - if (!CMC_(PFX, _empty)(_list_)) \ - { \ - memmove(_list_->buffer + 1, _list_->buffer, \ - _list_->count * sizeof(V)); \ - } \ - \ - _list_->buffer[0] = value; \ - \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ - { \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (CMC_(PFX, _full)(_list_)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + index + 1, _list_->buffer + index, \ - (_list_->count - index) * sizeof(V)); \ - \ - _list_->buffer[index] = value; \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _full)(_list_)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ - return false; \ - } \ - \ - _list_->buffer[_list_->count++] = value; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - memmove(_list_->buffer, _list_->buffer + 1, \ - (_list_->count - 1) * sizeof(V)); \ - \ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - memmove(_list_->buffer + index, _list_->buffer + index + 1, \ - (_list_->count - index - 1) * sizeof(V)); \ - \ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - return false; \ - \ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->buffer[0]; \ - } \ - \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->buffer[index]; \ - } \ - \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return &(_list_->buffer[index]); \ - } \ - \ - V CMC_(PFX, _back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->buffer[_list_->count - 1]; \ - } \ - \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ - bool from_start) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - size_t result = _list_->count; \ - \ - if (from_start) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \ - { \ - result = i; \ - break; \ - } \ - } \ - } \ - else \ - { \ - for (size_t i = _list_->count; i > 0; i--) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i - 1], value) == 0) \ - { \ - result = i - 1; \ - break; \ - } \ - } \ - } \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _list_) \ - { \ - return _list_->count >= _list_->capacity; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ - \ - bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size) \ - { \ - return _list_->count + size <= _list_->capacity; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ - { \ - return _list_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->capacity == capacity) \ - return true; \ - \ - if (capacity < _list_->count) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - V *new_buffer = \ - _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - /* TODO zero out new slots */ \ - \ - _list_->buffer = new_buffer; \ - _list_->capacity = capacity; \ - \ - if (_list_->callbacks && _list_->callbacks->resize) \ - _list_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, \ - _list_->alloc, _list_->callbacks); \ - \ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - if (_list_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ - } \ - else \ +#define CMC_CMC_LIST_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + /* None */ \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ +\ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_list_) \ + return NULL; \ +\ + _list_->buffer = alloc->calloc(capacity, sizeof(V)); \ +\ + if (!_list_->buffer) \ + { \ + alloc->free(_list_); \ + return NULL; \ + } \ +\ + _list_->capacity = capacity; \ + _list_->count = 0; \ + _list_->flag = CMC_FLAG_OK; \ + _list_->f_val = f_val; \ + _list_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ +\ + return _list_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ + { \ + if (_list_->f_val->free) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + _list_->f_val->free(_list_->buffer[i]); \ + } \ +\ + memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ +\ + _list_->count = 0; \ + _list_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _list_) \ + { \ + if (_list_->f_val->free) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + _list_->f_val->free(_list_->buffer[i]); \ + } \ +\ + _list_->alloc->free(_list_->buffer); \ + _list_->alloc->free(_list_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _list_->alloc = &cmc_alloc_node_default; \ + else \ + _list_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ +\ + _list_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ + { \ + if (CMC_(PFX, _full)(_list_)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ + return false; \ + } \ +\ + if (!CMC_(PFX, _empty)(_list_)) \ + { \ + memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(V)); \ + } \ +\ + _list_->buffer[0] = value; \ +\ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ + { \ + if (index > _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ +\ + if (CMC_(PFX, _full)(_list_)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ + return false; \ + } \ +\ + memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \ +\ + _list_->buffer[index] = value; \ + _list_->count++; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ + { \ + if (CMC_(PFX, _full)(_list_)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ + return false; \ + } \ +\ + _list_->buffer[_list_->count++] = value; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(V)); \ +\ + _list_->buffer[--_list_->count] = (V){ 0 }; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ +\ + memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(V)); \ +\ + _list_->buffer[--_list_->count] = (V){ 0 }; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + return false; \ +\ + _list_->buffer[--_list_->count] = (V){ 0 }; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _front)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return _list_->buffer[0]; \ + } \ +\ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return (V){ 0 }; \ + } \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return _list_->buffer[index]; \ + } \ +\ + V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return NULL; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return &(_list_->buffer[index]); \ + } \ +\ + V CMC_(PFX, _back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return _list_->buffer[_list_->count - 1]; \ + } \ +\ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start) \ + { \ + _list_->flag = CMC_FLAG_OK; \ +\ + size_t result = _list_->count; \ +\ + if (from_start) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \ + { \ + result = i; \ + break; \ + } \ + } \ + } \ + else \ + { \ + for (size_t i = _list_->count; i > 0; i--) \ + { \ + if (_list_->f_val->cmp(_list_->buffer[i - 1], value) == 0) \ + { \ + result = i - 1; \ + break; \ + } \ + } \ + } \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ + { \ + _list_->flag = CMC_FLAG_OK; \ +\ + bool result = false; \ +\ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \ + { \ + result = true; \ + break; \ + } \ + } \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ + { \ + return _list_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _list_) \ + { \ + return _list_->count >= _list_->capacity; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _list_) \ + { \ + return _list_->count; \ + } \ +\ + bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size) \ + { \ + return _list_->count + size <= _list_->capacity; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ + { \ + return _list_->capacity; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _list_) \ + { \ + return _list_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \ + { \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->capacity == capacity) \ + return true; \ +\ + if (capacity < _list_->count) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + V *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \ +\ + if (!new_buffer) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + /* TODO zero out new slots */ \ +\ + _list_->buffer = new_buffer; \ + _list_->capacity = capacity; \ +\ + if (_list_->callbacks && _list_->callbacks->resize) \ + _list_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, _list_->alloc, NULL); \ +\ + if (!result) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \ +\ + if (_list_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ + } \ + else \ memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \ - \ - result->count = _list_->count; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - _list1_->flag = CMC_FLAG_OK; \ - _list2_->flag = CMC_FLAG_OK; \ - \ - if (_list1_->count != _list2_->count) \ - return false; \ - \ - for (size_t i = 0; i < _list1_->count; i++) \ - { \ - if (0 != \ - _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) \ - return false; \ - } \ - \ - return true; \ +\ + result->count = _list_->count; \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ + { \ + _list1_->flag = CMC_FLAG_OK; \ + _list2_->flag = CMC_FLAG_OK; \ +\ + if (_list1_->count != _list2_->count) \ + return false; \ +\ + for (size_t i = 0; i < _list1_->count; i++) \ + { \ + if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) \ + return false; \ + } \ +\ + return true; \ } #endif /* CMC_CMC_LIST_H */ diff --git a/src/cmc/queue.h b/src/cmc/queue.h index 43a897a..dda6d1f 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -67,733 +67,681 @@ static const char *cmc_cmc_string_fmt_queue = "struct %s<%s> " /** * Core Queue implementation */ -#define CMC_CMC_QUEUE_CORE(PARAMS) \ +#define CMC_CMC_QUEUE_CORE(PARAMS) \ CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \ CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) -#define CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \ - CMC_CMC_QUEUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \ + CMC_CMC_QUEUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) \ - CMC_CMC_QUEUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) \ + CMC_CMC_QUEUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_QUEUE_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Queue Structure */ \ - struct SNAME \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ - \ - /* Current circular array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Index representing the front of the queue */ \ - size_t front; \ - \ - /* Index representing the back of the queue */ \ - size_t back; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Queue Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target queue */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _queue_); \ - void CMC_(PFX, _free)(struct SNAME * _queue_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _queue_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value); \ - bool CMC_(PFX, _dequeue)(struct SNAME * _queue_); \ - /* Element Access */ \ - V CMC_(PFX, _peek)(struct SNAME * _queue_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _queue_); \ - bool CMC_(PFX, _full)(struct SNAME * _queue_); \ - size_t CMC_(PFX, _count)(struct SNAME * _queue_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _queue_); \ - int CMC_(PFX, _flag)(struct SNAME * _queue_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_); \ +#define CMC_CMC_QUEUE_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* Queue Structure */ \ + struct SNAME \ + { \ + /* Dynamic circular array of elements */ \ + V *buffer; \ +\ + /* Current circular array capacity */ \ + size_t capacity; \ +\ + /* Current amount of elements */ \ + size_t count; \ +\ + /* Index representing the front of the queue */ \ + size_t front; \ +\ + /* Index representing the back of the queue */ \ + size_t back; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Queue Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target queue */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _queue_); \ + void CMC_(PFX, _free)(struct SNAME * _queue_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _queue_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value); \ + bool CMC_(PFX, _dequeue)(struct SNAME * _queue_); \ + /* Element Access */ \ + V CMC_(PFX, _peek)(struct SNAME * _queue_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _queue_); \ + bool CMC_(PFX, _full)(struct SNAME * _queue_); \ + size_t CMC_(PFX, _count)(struct SNAME * _queue_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _queue_); \ + int CMC_(PFX, _flag)(struct SNAME * _queue_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_); \ bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _queue_); \ - bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _queue_); \ + bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr); \ +\ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_QUEUE_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_queue_) \ - return NULL; \ - \ - _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_queue_->buffer) \ - { \ - alloc->free(_queue_); \ - return NULL; \ - } \ - \ - _queue_->capacity = capacity; \ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->back = 0; \ - _queue_->flag = CMC_FLAG_OK; \ - _queue_->f_val = f_val; \ - _queue_->alloc = alloc; \ - _queue_->callbacks = NULL; \ - \ - return _queue_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_queue_) \ - return NULL; \ - \ - _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_queue_->buffer) \ - { \ - alloc->free(_queue_); \ - return NULL; \ - } \ - \ - _queue_->capacity = capacity; \ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->back = 0; \ - _queue_->flag = CMC_FLAG_OK; \ - _queue_->f_val = f_val; \ - _queue_->alloc = alloc; \ - _queue_->callbacks = callbacks; \ - \ - return _queue_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _queue_) \ - { \ - if (_queue_->f_val->free) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - _queue_->f_val->free(_queue_->buffer[i]); \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - \ - memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \ - \ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->back = 0; \ - _queue_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _queue_) \ - { \ - if (_queue_->f_val->free) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - _queue_->f_val->free(_queue_->buffer[i]); \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - \ - _queue_->alloc->free(_queue_->buffer); \ - _queue_->alloc->free(_queue_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _queue_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _queue_->alloc = &cmc_alloc_node_default; \ - else \ - _queue_->alloc = alloc; \ - \ - _queue_->callbacks = callbacks; \ - \ - _queue_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value) \ - { \ - if (CMC_(PFX, _full)(_queue_)) \ - { \ - if (!CMC_(PFX, _resize)(_queue_, _queue_->capacity * 2)) \ - return false; \ - } \ - \ - _queue_->buffer[_queue_->back] = value; \ - \ - _queue_->back = \ - (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \ - _queue_->count++; \ - _queue_->flag = CMC_FLAG_OK; \ - \ - if (_queue_->callbacks && _queue_->callbacks->create) \ - _queue_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _dequeue)(struct SNAME * _queue_) \ - { \ - if (CMC_(PFX, _empty)(_queue_)) \ - { \ - _queue_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _queue_->buffer[_queue_->front] = (V){ 0 }; \ - \ - _queue_->front = (_queue_->front == _queue_->capacity - 1) \ - ? 0 \ - : _queue_->front + 1; \ - _queue_->count--; \ - _queue_->flag = CMC_FLAG_OK; \ - \ - if (_queue_->callbacks && _queue_->callbacks->delete) \ - _queue_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _peek)(struct SNAME * _queue_) \ - { \ - if (CMC_(PFX, _empty)(_queue_)) \ - { \ - _queue_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _queue_->flag = CMC_FLAG_OK; \ - \ - if (_queue_->callbacks && _queue_->callbacks->read) \ - _queue_->callbacks->read(); \ - \ - return _queue_->buffer[_queue_->front]; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value) \ - { \ - _queue_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - \ - if (_queue_->callbacks && _queue_->callbacks->read) \ - _queue_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _queue_) \ - { \ - return _queue_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _queue_) \ - { \ - return _queue_->count >= _queue_->capacity; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _queue_) \ - { \ - return _queue_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _queue_) \ - { \ - return _queue_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _queue_) \ - { \ - return _queue_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity) \ - { \ - if (_queue_->capacity == capacity) \ - goto success; \ - \ - if (capacity < _queue_->count) \ - { \ - _queue_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - V *new_buffer = _queue_->alloc->malloc(sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - { \ - _queue_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - new_buffer[j] = _queue_->buffer[i]; \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - \ - _queue_->alloc->free(_queue_->buffer); \ - \ - _queue_->buffer = new_buffer; \ - _queue_->capacity = capacity; \ - _queue_->front = 0; \ - _queue_->back = _queue_->count; \ - \ - success: \ - \ - _queue_->flag = CMC_FLAG_OK; \ - \ - if (_queue_->callbacks && _queue_->callbacks->resize) \ - _queue_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_queue_->capacity, _queue_->f_val, \ - _queue_->alloc, _queue_->callbacks); \ - \ - if (!result) \ - { \ - _queue_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_queue_->f_val->cpy) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - result->buffer[j] = _queue_->f_val->cpy(_queue_->buffer[i]); \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - else \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - result->buffer[j] = _queue_->buffer[i]; \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - \ - result->count = _queue_->count; \ - result->front = 0; \ - result->back = _queue_->count; \ - \ - _queue_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_) \ - { \ - _queue1_->flag = CMC_FLAG_OK; \ - _queue2_->flag = CMC_FLAG_OK; \ - \ - if (_queue1_->count != _queue2_->count) \ - return false; \ - \ - size_t i, j, k; \ - for (i = _queue1_->front, j = _queue2_->front, k = 0; \ - k < _queue1_->count; k++) \ - { \ - if (_queue1_->f_val->cmp(_queue1_->buffer[i], \ - _queue2_->buffer[j]) != 0) \ - return false; \ - \ - i = (i + 1) % _queue1_->capacity; \ - j = (j + 1) % _queue2_->capacity; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _queue_) \ - { \ - struct cmc_string str; \ - struct SNAME *q_ = _queue_; \ - \ - int n = \ - snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_queue, #SNAME, \ - #V, q_, q_->buffer, q_->capacity, q_->count, q_->front, \ - q_->back, q_->flag, q_->f_val, q_->alloc, q_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) \ - return false; \ - \ - i = (i + 1) % _queue_->capacity; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->front; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - if (iter.target->back == 0) \ - iter.cursor = iter.target->capacity - 1; \ - else \ - iter.cursor = iter.target->back - 1; \ - \ - iter.index = iter.target->count - 1; \ - } \ - else \ - { \ - iter.cursor = 0; \ - iter.index = 0; \ - } \ - \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - if (iter->target->back == 0) \ - iter->cursor = iter->target->capacity - 1; \ - else \ - iter->cursor = iter->target->back - 1; \ - \ - iter->index = iter->target->count - 1; \ - \ - iter->start = false; \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \ - : iter->cursor - 1; \ - iter->index--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index += steps; \ - iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index -= steps; \ - \ - /* Prevent underflow */ \ - if (iter->cursor < steps) \ - iter->cursor += iter->target->capacity; \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ +#define CMC_CMC_QUEUE_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + /* None */ \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ +\ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_queue_) \ + return NULL; \ +\ + _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \ +\ + if (!_queue_->buffer) \ + { \ + alloc->free(_queue_); \ + return NULL; \ + } \ +\ + _queue_->capacity = capacity; \ + _queue_->count = 0; \ + _queue_->front = 0; \ + _queue_->back = 0; \ + _queue_->flag = CMC_FLAG_OK; \ + _queue_->f_val = f_val; \ + _queue_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_queue_, callbacks); \ +\ + return _queue_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _queue_) \ + { \ + if (_queue_->f_val->free) \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + _queue_->f_val->free(_queue_->buffer[i]); \ +\ + i = (i + 1) % _queue_->capacity; \ + } \ + } \ +\ + memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \ +\ + _queue_->count = 0; \ + _queue_->front = 0; \ + _queue_->back = 0; \ + _queue_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _queue_) \ + { \ + if (_queue_->f_val->free) \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + _queue_->f_val->free(_queue_->buffer[i]); \ +\ + i = (i + 1) % _queue_->capacity; \ + } \ + } \ +\ + _queue_->alloc->free(_queue_->buffer); \ + _queue_->alloc->free(_queue_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _queue_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _queue_->alloc = &cmc_alloc_node_default; \ + else \ + _queue_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_queue_, callbacks); \ +\ + _queue_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value) \ + { \ + if (CMC_(PFX, _full)(_queue_)) \ + { \ + if (!CMC_(PFX, _resize)(_queue_, _queue_->capacity * 2)) \ + return false; \ + } \ +\ + _queue_->buffer[_queue_->back] = value; \ +\ + _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \ + _queue_->count++; \ + _queue_->flag = CMC_FLAG_OK; \ +\ + if (_queue_->callbacks && _queue_->callbacks->create) \ + _queue_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _dequeue)(struct SNAME * _queue_) \ + { \ + if (CMC_(PFX, _empty)(_queue_)) \ + { \ + _queue_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + _queue_->buffer[_queue_->front] = (V){ 0 }; \ +\ + _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \ + _queue_->count--; \ + _queue_->flag = CMC_FLAG_OK; \ +\ + if (_queue_->callbacks && _queue_->callbacks->delete) \ + _queue_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _peek)(struct SNAME * _queue_) \ + { \ + if (CMC_(PFX, _empty)(_queue_)) \ + { \ + _queue_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _queue_->flag = CMC_FLAG_OK; \ +\ + if (_queue_->callbacks && _queue_->callbacks->read) \ + _queue_->callbacks->read(); \ +\ + return _queue_->buffer[_queue_->front]; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value) \ + { \ + _queue_->flag = CMC_FLAG_OK; \ +\ + bool result = false; \ +\ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) \ + { \ + result = true; \ + break; \ + } \ +\ + i = (i + 1) % _queue_->capacity; \ + } \ +\ + if (_queue_->callbacks && _queue_->callbacks->read) \ + _queue_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _queue_) \ + { \ + return _queue_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _queue_) \ + { \ + return _queue_->count >= _queue_->capacity; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _queue_) \ + { \ + return _queue_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _queue_) \ + { \ + return _queue_->capacity; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _queue_) \ + { \ + return _queue_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity) \ + { \ + if (_queue_->capacity == capacity) \ + goto success; \ +\ + if (capacity < _queue_->count) \ + { \ + _queue_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + V *new_buffer = _queue_->alloc->malloc(sizeof(V) * capacity); \ +\ + if (!new_buffer) \ + { \ + _queue_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + new_buffer[j] = _queue_->buffer[i]; \ +\ + i = (i + 1) % _queue_->capacity; \ + } \ +\ + _queue_->alloc->free(_queue_->buffer); \ +\ + _queue_->buffer = new_buffer; \ + _queue_->capacity = capacity; \ + _queue_->front = 0; \ + _queue_->back = _queue_->count; \ +\ + success: \ +\ + _queue_->flag = CMC_FLAG_OK; \ +\ + if (_queue_->callbacks && _queue_->callbacks->resize) \ + _queue_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)(_queue_->capacity, _queue_->f_val, _queue_->alloc, NULL); \ +\ + if (!result) \ + { \ + _queue_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _queue_->callbacks); \ +\ + if (_queue_->f_val->cpy) \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + result->buffer[j] = _queue_->f_val->cpy(_queue_->buffer[i]); \ +\ + i = (i + 1) % _queue_->capacity; \ + } \ + } \ + else \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + result->buffer[j] = _queue_->buffer[i]; \ +\ + i = (i + 1) % _queue_->capacity; \ + } \ + } \ +\ + result->count = _queue_->count; \ + result->front = 0; \ + result->back = _queue_->count; \ +\ + _queue_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_) \ + { \ + _queue1_->flag = CMC_FLAG_OK; \ + _queue2_->flag = CMC_FLAG_OK; \ +\ + if (_queue1_->count != _queue2_->count) \ + return false; \ +\ + size_t i, j, k; \ + for (i = _queue1_->front, j = _queue2_->front, k = 0; k < _queue1_->count; k++) \ + { \ + if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) \ + return false; \ +\ + i = (i + 1) % _queue1_->capacity; \ + j = (j + 1) % _queue2_->capacity; \ + } \ +\ + return true; \ + } \ +\ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _queue_) \ + { \ + struct cmc_string str; \ + struct SNAME *q_ = _queue_; \ +\ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_queue, #SNAME, #V, q_, q_->buffer, q_->capacity, \ + q_->count, q_->front, q_->back, q_->flag, q_->f_val, q_->alloc, q_->callbacks); \ +\ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr) \ + { \ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) \ + return false; \ +\ + i = (i + 1) % _queue_->capacity; \ + } \ +\ + return true; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->front; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + if (iter.target->back == 0) \ + iter.cursor = iter.target->capacity - 1; \ + else \ + iter.cursor = iter.target->back - 1; \ +\ + iter.index = iter.target->count - 1; \ + } \ + else \ + { \ + iter.cursor = 0; \ + iter.index = 0; \ + } \ +\ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->front; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = false; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + if (iter->target->back == 0) \ + iter->cursor = iter->target->capacity - 1; \ + else \ + iter->cursor = iter->target->back - 1; \ +\ + iter->index = iter->target->count - 1; \ +\ + iter->start = false; \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ + iter->index++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \ + iter->index--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->index += steps; \ + iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->index -= steps; \ +\ + /* Prevent underflow */ \ + if (iter->cursor < steps) \ + iter->cursor += iter->target->capacity; \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->target->buffer[iter->cursor]); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ } #endif /* CMC_CMC_QUEUE_H */ diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h index ac0be3f..076e23b 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc/sortedlist.h @@ -45,862 +45,804 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " /** * Core SortedList implementation */ -#define CMC_CMC_SORTEDLIST_CORE(PARAMS) \ +#define CMC_CMC_SORTEDLIST_CORE(PARAMS) \ CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) \ CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) #define CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_CMC_SORTEDLIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_CMC_SORTEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_SORTEDLIST_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flag if the list is sorted or not, used by lazy evaluation */ \ - bool is_sorted; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target list */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index); \ - /* Element Access */ \ - V CMC_(PFX, _max)(struct SNAME * _list_); \ - V CMC_(PFX, _min)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ - bool from_start); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - bool CMC_(PFX, _full)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ - void CMC_(PFX, _sort)(struct SNAME * _list_); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ +#define CMC_CMC_SORTEDLIST_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* List Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ +\ + /* Current array capacity */ \ + size_t capacity; \ +\ + /* Current amount of elements */ \ + size_t count; \ +\ + /* Flag if the list is sorted or not, used by lazy evaluation */ \ + bool is_sorted; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* List Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target list */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _list_); \ + void CMC_(PFX, _free)(struct SNAME * _list_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index); \ + /* Element Access */ \ + V CMC_(PFX, _max)(struct SNAME * _list_); \ + V CMC_(PFX, _min)(struct SNAME * _list_); \ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _list_); \ + bool CMC_(PFX, _full)(struct SNAME * _list_); \ + size_t CMC_(PFX, _count)(struct SNAME * _list_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ + int CMC_(PFX, _flag)(struct SNAME * _list_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ + void CMC_(PFX, _sort)(struct SNAME * _list_); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \ +\ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_SORTEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, \ - V value); \ - static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, \ - V value); \ - void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), \ - size_t low, size_t high); \ - void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), \ - size_t low, size_t high); \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_list_->buffer) \ - { \ - alloc->free(_list_); \ - return NULL; \ - } \ - \ - _list_->capacity = capacity; \ - _list_->count = 0; \ - _list_->is_sorted = false; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = NULL; \ - \ - return _list_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_list_) \ - return NULL; \ - \ - _list_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_list_->buffer) \ - { \ - alloc->free(_list_); \ - return NULL; \ - } \ - \ - _list_->capacity = capacity; \ - _list_->count = 0; \ - _list_->is_sorted = false; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - _list_->callbacks = callbacks; \ - \ - return _list_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ - \ - memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ - \ - _list_->count = 0; \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ - \ - _list_->alloc->free(_list_->buffer); \ - _list_->alloc->free(_list_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _list_->alloc = &cmc_alloc_node_default; \ - else \ - _list_->alloc = alloc; \ - \ - _list_->callbacks = callbacks; \ - \ - _list_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _full)(_list_)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->capacity * 2)) \ - return false; \ - } \ - \ - _list_->buffer[_list_->count++] = value; \ - \ - _list_->is_sorted = false; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - memmove(_list_->buffer + index, _list_->buffer + index + 1, \ - (_list_->count - index) * sizeof(V)); \ - \ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _max)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - CMC_(PFX, _sort)(_list_); \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->buffer[_list_->count - 1]; \ - } \ - \ - V CMC_(PFX, _min)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - CMC_(PFX, _sort)(_list_); \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->buffer[0]; \ - } \ - \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ - \ - CMC_(PFX, _sort)(_list_); \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return _list_->buffer[index]; \ - } \ - \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, \ - bool from_start) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - CMC_(PFX, _sort)(_list_); \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - if (from_start) \ - { \ - return CMC_(PFX, _impl_binary_search_first)(_list_, value); \ - } \ - \ - return CMC_(PFX, _impl_binary_search_last)(_list_, value); \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (CMC_(PFX, _empty)(_list_)) \ - return false; \ - \ - CMC_(PFX, _sort)(_list_); \ - \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ - \ - return CMC_(PFX, _impl_binary_search_first)(_list_, value) < \ - _list_->count; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _list_) \ - { \ - return _list_->count >= _list_->capacity; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ - { \ - return _list_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \ - { \ - if (_list_->capacity == capacity) \ - goto success; \ - \ - if (capacity < _list_->count) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - V *new_buffer = \ - _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - /* TODO zero out remaining slots */ \ - \ - _list_->buffer = new_buffer; \ - _list_->capacity = capacity; \ - \ - success: \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->resize) \ - _list_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - void CMC_(PFX, _sort)(struct SNAME * _list_) \ - { \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (!_list_->is_sorted && _list_->count > 1) \ - { \ - CMC_(PFX, _impl_sort_quicksort) \ - (_list_->buffer, _list_->f_val->cmp, 0, _list_->count - 1); \ - \ - _list_->is_sorted = true; \ - } \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, \ - _list_->alloc, _list_->callbacks); \ - \ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_list_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ - } \ - else \ +#define CMC_CMC_SORTEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, V value); \ + static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, V value); \ + void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), size_t low, size_t high); \ + void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), size_t low, size_t high); \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_list_) \ + return NULL; \ +\ + _list_->buffer = alloc->calloc(capacity, sizeof(V)); \ +\ + if (!_list_->buffer) \ + { \ + alloc->free(_list_); \ + return NULL; \ + } \ +\ + _list_->capacity = capacity; \ + _list_->count = 0; \ + _list_->is_sorted = false; \ + _list_->flag = CMC_FLAG_OK; \ + _list_->f_val = f_val; \ + _list_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ +\ + return _list_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ + { \ + if (_list_->f_val->free) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + _list_->f_val->free(_list_->buffer[i]); \ + } \ +\ + memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ +\ + _list_->count = 0; \ + _list_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _list_) \ + { \ + if (_list_->f_val->free) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + _list_->f_val->free(_list_->buffer[i]); \ + } \ +\ + _list_->alloc->free(_list_->buffer); \ + _list_->alloc->free(_list_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _list_->alloc = &cmc_alloc_node_default; \ + else \ + _list_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ +\ + _list_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _list_, V value) \ + { \ + if (CMC_(PFX, _full)(_list_)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->capacity * 2)) \ + return false; \ + } \ +\ + _list_->buffer[_list_->count++] = value; \ +\ + _list_->is_sorted = false; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ +\ + memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(V)); \ +\ + _list_->buffer[--_list_->count] = (V){ 0 }; \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _max)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + CMC_(PFX, _sort)(_list_); \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return _list_->buffer[_list_->count - 1]; \ + } \ +\ + V CMC_(PFX, _min)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + CMC_(PFX, _sort)(_list_); \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return _list_->buffer[0]; \ + } \ +\ + V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return (V){ 0 }; \ + } \ +\ + CMC_(PFX, _sort)(_list_); \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return _list_->buffer[index]; \ + } \ +\ + size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start) \ + { \ + _list_->flag = CMC_FLAG_OK; \ +\ + CMC_(PFX, _sort)(_list_); \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + if (from_start) \ + { \ + return CMC_(PFX, _impl_binary_search_first)(_list_, value); \ + } \ +\ + return CMC_(PFX, _impl_binary_search_last)(_list_, value); \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ + { \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (CMC_(PFX, _empty)(_list_)) \ + return false; \ +\ + CMC_(PFX, _sort)(_list_); \ +\ + if (_list_->callbacks && _list_->callbacks->read) \ + _list_->callbacks->read(); \ +\ + return CMC_(PFX, _impl_binary_search_first)(_list_, value) < _list_->count; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ + { \ + return _list_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _list_) \ + { \ + return _list_->count >= _list_->capacity; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _list_) \ + { \ + return _list_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ + { \ + return _list_->capacity; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _list_) \ + { \ + return _list_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \ + { \ + if (_list_->capacity == capacity) \ + goto success; \ +\ + if (capacity < _list_->count) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + V *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \ +\ + if (!new_buffer) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + /* TODO zero out remaining slots */ \ +\ + _list_->buffer = new_buffer; \ + _list_->capacity = capacity; \ +\ + success: \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->resize) \ + _list_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + void CMC_(PFX, _sort)(struct SNAME * _list_) \ + { \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (!_list_->is_sorted && _list_->count > 1) \ + { \ + CMC_(PFX, _impl_sort_quicksort) \ + (_list_->buffer, _list_->f_val->cmp, 0, _list_->count - 1); \ +\ + _list_->is_sorted = true; \ + } \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, _list_->alloc, NULL); \ +\ + if (!result) \ + { \ + _list_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \ +\ + if (_list_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _list_->count; i++) \ + result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ + } \ + else \ memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \ - \ - result->count = _list_->count; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - if (_list1_->count != _list2_->count) \ - return false; \ - \ - CMC_(PFX, _sort)(_list1_); \ - CMC_(PFX, _sort)(_list2_); \ - \ - for (size_t i = 0; i < _list1_->count; i++) \ - { \ - if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \ - 0) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ - { \ - struct cmc_string str; \ - struct SNAME *l_ = _list_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_sortedlist, \ - #SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \ - l_->is_sorted ? "true" : "false", l_->flag, \ - l_->f_val, l_->alloc, l_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ - { \ - CMC_(PFX, _sort)(_list_); \ - \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - CMC_(PFX, _sort)(target); \ - \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - CMC_(PFX, _sort)(target); \ - \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->target->count - 1; \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } \ - \ - static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, \ - V value) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - return 1; \ - \ - size_t L = 0; \ - size_t R = _list_->count; \ - \ - while (L < R) \ - { \ - size_t M = L + (R - L) / 2; \ - \ - if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) \ - L = M + 1; \ - else \ - R = M; \ - } \ - \ - if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) \ - return L; \ - \ - /* Not found */ \ - return _list_->count; \ - } \ - \ - static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, \ - V value) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - return 1; \ - \ - size_t L = 0; \ - size_t R = _list_->count; \ - \ - while (L < R) \ - { \ - size_t M = L + (R - L) / 2; \ - \ - if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) \ - R = M; \ - else \ - L = M + 1; \ - } \ - \ - if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) \ - return L - 1; \ - \ - /* Not found */ \ - return _list_->count; \ - } \ - \ - /* Characteristics of this quicksort implementation: */ \ - /* - Hybrid: uses insertion sort for small arrays */ \ - /* - Partition: Lomuto's Method */ \ - /* - Tail recursion: minimize recursion depth */ \ - void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), \ - size_t low, size_t high) \ - { \ - while (low < high) \ - { \ - /* Quicksort performs poorly for smaller arrays so let */ \ - /* insertion sort do the job */ \ - if (high - low < 10) \ - { \ - CMC_(PFX, _impl_sort_insertion)(array, cmp, low, high); \ - break; \ - } \ - else \ - { \ - /* Partition */ \ - V pivot = array[high]; \ - \ - size_t pindex = low; \ - \ - for (size_t i = low; i < high; i++) \ - { \ - if (cmp(array[i], pivot) <= 0) \ - { \ - V _tmp_ = array[i]; \ - array[i] = array[pindex]; \ - array[pindex] = _tmp_; \ - \ - pindex++; \ - } \ - } \ - \ - V _tmp_ = array[pindex]; \ - array[pindex] = array[high]; \ - array[high] = _tmp_; \ - \ - /* Tail recursion */ \ - if (pindex - low < high - pindex) \ - { \ - CMC_(PFX, _impl_sort_quicksort) \ - (array, cmp, low, pindex - 1); \ - \ - low = pindex + 1; \ - } \ - else \ - { \ - CMC_(PFX, _impl_sort_quicksort) \ - (array, cmp, pindex + 1, high); \ - \ - high = pindex - 1; \ - } \ - } \ - } \ - } \ - \ - void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), \ - size_t low, size_t high) \ - { \ - for (size_t i = low + 1; i <= high; i++) \ - { \ - V _tmp_ = array[i]; \ - size_t j = i; \ - \ - while (j > low && cmp(array[j - 1], _tmp_) > 0) \ - { \ - array[j] = array[j - 1]; \ - j--; \ - } \ - \ - array[j] = _tmp_; \ - } \ +\ + result->count = _list_->count; \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ + { \ + if (_list1_->count != _list2_->count) \ + return false; \ +\ + CMC_(PFX, _sort)(_list1_); \ + CMC_(PFX, _sort)(_list2_); \ +\ + for (size_t i = 0; i < _list1_->count; i++) \ + { \ + if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ + { \ + struct cmc_string str; \ + struct SNAME *l_ = _list_; \ +\ + int n = \ + snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_sortedlist, #SNAME, #V, l_, l_->buffer, l_->capacity, \ + l_->count, l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, l_->callbacks); \ +\ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ + { \ + CMC_(PFX, _sort)(_list_); \ +\ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + CMC_(PFX, _sort)(target); \ +\ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + CMC_(PFX, _sort)(target); \ +\ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->target->count - 1; \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor += steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ + } \ +\ + static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, V value) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + return 1; \ +\ + size_t L = 0; \ + size_t R = _list_->count; \ +\ + while (L < R) \ + { \ + size_t M = L + (R - L) / 2; \ +\ + if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) \ + L = M + 1; \ + else \ + R = M; \ + } \ +\ + if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) \ + return L; \ +\ + /* Not found */ \ + return _list_->count; \ + } \ +\ + static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, V value) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + return 1; \ +\ + size_t L = 0; \ + size_t R = _list_->count; \ +\ + while (L < R) \ + { \ + size_t M = L + (R - L) / 2; \ +\ + if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) \ + R = M; \ + else \ + L = M + 1; \ + } \ +\ + if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) \ + return L - 1; \ +\ + /* Not found */ \ + return _list_->count; \ + } \ +\ + /* Characteristics of this quicksort implementation: */ \ + /* - Hybrid: uses insertion sort for small arrays */ \ + /* - Partition: Lomuto's Method */ \ + /* - Tail recursion: minimize recursion depth */ \ + void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), size_t low, size_t high) \ + { \ + while (low < high) \ + { \ + /* Quicksort performs poorly for smaller arrays so let */ \ + /* insertion sort do the job */ \ + if (high - low < 10) \ + { \ + CMC_(PFX, _impl_sort_insertion)(array, cmp, low, high); \ + break; \ + } \ + else \ + { \ + /* Partition */ \ + V pivot = array[high]; \ +\ + size_t pindex = low; \ +\ + for (size_t i = low; i < high; i++) \ + { \ + if (cmp(array[i], pivot) <= 0) \ + { \ + V _tmp_ = array[i]; \ + array[i] = array[pindex]; \ + array[pindex] = _tmp_; \ +\ + pindex++; \ + } \ + } \ +\ + V _tmp_ = array[pindex]; \ + array[pindex] = array[high]; \ + array[high] = _tmp_; \ +\ + /* Tail recursion */ \ + if (pindex - low < high - pindex) \ + { \ + CMC_(PFX, _impl_sort_quicksort) \ + (array, cmp, low, pindex - 1); \ +\ + low = pindex + 1; \ + } \ + else \ + { \ + CMC_(PFX, _impl_sort_quicksort) \ + (array, cmp, pindex + 1, high); \ +\ + high = pindex - 1; \ + } \ + } \ + } \ + } \ +\ + void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), size_t low, size_t high) \ + { \ + for (size_t i = low + 1; i <= high; i++) \ + { \ + V _tmp_ = array[i]; \ + size_t j = i; \ +\ + while (j > low && cmp(array[j - 1], _tmp_) > 0) \ + { \ + array[j] = array[j - 1]; \ + j--; \ + } \ +\ + array[j] = _tmp_; \ + } \ } #endif /* CMC_CMC_SORTEDLIST_H */ diff --git a/src/cmc/stack.h b/src/cmc/stack.h index defd64a..6207d35 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -50,645 +50,599 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " /** * Core Stack implementation */ -#define CMC_CMC_STACK_CORE(PARAMS) \ +#define CMC_CMC_STACK_CORE(PARAMS) \ CMC_CMC_STACK_CORE_HEADER(PARAMS) \ CMC_CMC_STACK_CORE_SOURCE(PARAMS) -#define CMC_CMC_STACK_CORE_HEADER(PARAMS) \ - CMC_CMC_STACK_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_STACK_CORE_HEADER(PARAMS) \ + CMC_CMC_STACK_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_STACK_CORE_SOURCE(PARAMS) \ - CMC_CMC_STACK_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_CMC_STACK_CORE_SOURCE(PARAMS) \ + CMC_CMC_STACK_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_STACK_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Stack Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ - \ - /* Current array capacity */ \ - size_t capacity; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Stack Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target stack */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _stack_); \ - void CMC_(PFX, _free)(struct SNAME * _stack_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _stack_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push)(struct SNAME * _stack_, V value); \ - bool CMC_(PFX, _pop)(struct SNAME * _stack_); \ - /* Element Access */ \ - V CMC_(PFX, _top)(struct SNAME * _stack_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _stack_); \ - bool CMC_(PFX, _full)(struct SNAME * _stack_); \ - size_t CMC_(PFX, _count)(struct SNAME * _stack_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _stack_); \ - int CMC_(PFX, _flag)(struct SNAME * _stack_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_); \ +#define CMC_CMC_STACK_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* Stack Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V *buffer; \ +\ + /* Current array capacity */ \ + size_t capacity; \ +\ + /* Current amount of elements */ \ + size_t count; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Stack Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target stack */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _stack_); \ + void CMC_(PFX, _free)(struct SNAME * _stack_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _stack_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _push)(struct SNAME * _stack_, V value); \ + bool CMC_(PFX, _pop)(struct SNAME * _stack_); \ + /* Element Access */ \ + V CMC_(PFX, _top)(struct SNAME * _stack_); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _stack_); \ + bool CMC_(PFX, _full)(struct SNAME * _stack_); \ + size_t CMC_(PFX, _count)(struct SNAME * _stack_); \ + size_t CMC_(PFX, _capacity)(struct SNAME * _stack_); \ + int CMC_(PFX, _flag)(struct SNAME * _stack_); \ + /* Collection Utility */ \ + bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_); \ bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _stack_); \ - bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _stack_); \ + bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr); \ +\ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_STACK_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - /* None */ \ - \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - if (capacity < 1) \ - return NULL; \ - \ - if (!f_val) \ - return NULL; \ - \ - struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_stack_) \ - return NULL; \ - \ - _stack_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_stack_->buffer) \ - { \ - alloc->free(_stack_); \ - return NULL; \ - } \ - \ - _stack_->capacity = capacity; \ - _stack_->count = 0; \ - _stack_->flag = CMC_FLAG_OK; \ - _stack_->f_val = f_val; \ - _stack_->alloc = alloc; \ - _stack_->callbacks = NULL; \ - \ - return _stack_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - if (capacity < 1) \ - return NULL; \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_stack_) \ - return NULL; \ - \ - _stack_->buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_stack_->buffer) \ - { \ - alloc->free(_stack_); \ - return NULL; \ - } \ - \ - _stack_->capacity = capacity; \ - _stack_->count = 0; \ - _stack_->flag = CMC_FLAG_OK; \ - _stack_->f_val = f_val; \ - _stack_->alloc = alloc; \ - _stack_->callbacks = callbacks; \ - \ - return _stack_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _stack_) \ - { \ - if (_stack_->f_val->free) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - _stack_->f_val->free(_stack_->buffer[i]); \ - } \ - \ - memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \ - \ - _stack_->count = 0; \ - _stack_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _stack_) \ - { \ - if (_stack_->f_val->free) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - _stack_->f_val->free(_stack_->buffer[i]); \ - } \ - \ - _stack_->alloc->free(_stack_->buffer); \ - _stack_->alloc->free(_stack_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _stack_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _stack_->alloc = &cmc_alloc_node_default; \ - else \ - _stack_->alloc = alloc; \ - \ - _stack_->callbacks = callbacks; \ - \ - _stack_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _push)(struct SNAME * _stack_, V value) \ - { \ - if (CMC_(PFX, _full)(_stack_)) \ - { \ - if (!CMC_(PFX, _resize)(_stack_, _stack_->capacity * 2)) \ - return false; \ - } \ - \ - _stack_->buffer[_stack_->count++] = value; \ - \ - _stack_->flag = CMC_FLAG_OK; \ - \ - if (_stack_->callbacks && _stack_->callbacks->create) \ - _stack_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _pop)(struct SNAME * _stack_) \ - { \ - if (CMC_(PFX, _empty)(_stack_)) \ - { \ - _stack_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - _stack_->buffer[--_stack_->count] = (V){ 0 }; \ - \ - _stack_->flag = CMC_FLAG_OK; \ - \ - if (_stack_->callbacks && _stack_->callbacks->delete) \ - _stack_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _top)(struct SNAME * _stack_) \ - { \ - if (CMC_(PFX, _empty)(_stack_)) \ - { \ - _stack_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ - \ - _stack_->flag = CMC_FLAG_OK; \ - \ - if (_stack_->callbacks && _stack_->callbacks->read) \ - _stack_->callbacks->read(); \ - \ - return _stack_->buffer[_stack_->count - 1]; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value) \ - { \ - _stack_->flag = CMC_FLAG_OK; \ - \ - bool result = false; \ - \ - for (size_t i = 0; i < _stack_->count; i++) \ - { \ - if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ - \ - if (_stack_->callbacks && _stack_->callbacks->read) \ - _stack_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _stack_) \ - { \ - return _stack_->count == 0; \ - } \ - \ - bool CMC_(PFX, _full)(struct SNAME * _stack_) \ - { \ - return _stack_->count >= _stack_->capacity; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _stack_) \ - { \ - return _stack_->count; \ - } \ - \ - size_t CMC_(PFX, _capacity)(struct SNAME * _stack_) \ - { \ - return _stack_->capacity; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _stack_) \ - { \ - return _stack_->flag; \ - } \ - \ - bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity) \ - { \ - if (_stack_->capacity == capacity) \ - goto success; \ - \ - if (capacity < _stack_->count) \ - { \ - _stack_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - V *new_buffer = \ - _stack_->alloc->realloc(_stack_->buffer, sizeof(V) * capacity); \ - \ - if (!new_buffer) \ - { \ - _stack_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - /* TODO zero out new slots */ \ - \ - _stack_->buffer = new_buffer; \ - _stack_->capacity = capacity; \ - \ - success: \ - \ - _stack_->flag = CMC_FLAG_OK; \ - \ - if (_stack_->callbacks && _stack_->callbacks->resize) \ - _stack_->callbacks->resize(); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_stack_->capacity, _stack_->f_val, \ - _stack_->alloc, _stack_->callbacks); \ - \ - if (!result) \ - { \ - _stack_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (_stack_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); \ - } \ - else \ - memcpy(result->buffer, _stack_->buffer, \ - sizeof(V) * _stack_->count); \ - \ - result->count = _stack_->count; \ - \ - _stack_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ +#define CMC_CMC_STACK_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + /* None */ \ +\ + struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (capacity < 1) \ + return NULL; \ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_stack_) \ + return NULL; \ +\ + _stack_->buffer = alloc->calloc(capacity, sizeof(V)); \ +\ + if (!_stack_->buffer) \ + { \ + alloc->free(_stack_); \ + return NULL; \ + } \ +\ + _stack_->capacity = capacity; \ + _stack_->count = 0; \ + _stack_->flag = CMC_FLAG_OK; \ + _stack_->f_val = f_val; \ + _stack_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_stack_, callbacks); \ +\ + return _stack_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _stack_) \ + { \ + if (_stack_->f_val->free) \ + { \ + for (size_t i = 0; i < _stack_->count; i++) \ + _stack_->f_val->free(_stack_->buffer[i]); \ + } \ +\ + memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \ +\ + _stack_->count = 0; \ + _stack_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _stack_) \ + { \ + if (_stack_->f_val->free) \ + { \ + for (size_t i = 0; i < _stack_->count; i++) \ + _stack_->f_val->free(_stack_->buffer[i]); \ + } \ +\ + _stack_->alloc->free(_stack_->buffer); \ + _stack_->alloc->free(_stack_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _stack_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _stack_->alloc = &cmc_alloc_node_default; \ + else \ + _stack_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_stack_, callbacks); \ +\ + _stack_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _push)(struct SNAME * _stack_, V value) \ + { \ + if (CMC_(PFX, _full)(_stack_)) \ + { \ + if (!CMC_(PFX, _resize)(_stack_, _stack_->capacity * 2)) \ + return false; \ + } \ +\ + _stack_->buffer[_stack_->count++] = value; \ +\ + _stack_->flag = CMC_FLAG_OK; \ +\ + if (_stack_->callbacks && _stack_->callbacks->create) \ + _stack_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop)(struct SNAME * _stack_) \ + { \ + if (CMC_(PFX, _empty)(_stack_)) \ + { \ + _stack_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + _stack_->buffer[--_stack_->count] = (V){ 0 }; \ +\ + _stack_->flag = CMC_FLAG_OK; \ +\ + if (_stack_->callbacks && _stack_->callbacks->delete) \ + _stack_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _top)(struct SNAME * _stack_) \ + { \ + if (CMC_(PFX, _empty)(_stack_)) \ + { \ + _stack_->flag = CMC_FLAG_EMPTY; \ + return (V){ 0 }; \ + } \ +\ + _stack_->flag = CMC_FLAG_OK; \ +\ + if (_stack_->callbacks && _stack_->callbacks->read) \ + _stack_->callbacks->read(); \ +\ + return _stack_->buffer[_stack_->count - 1]; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value) \ + { \ + _stack_->flag = CMC_FLAG_OK; \ +\ + bool result = false; \ +\ + for (size_t i = 0; i < _stack_->count; i++) \ + { \ + if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) \ + { \ + result = true; \ + break; \ + } \ + } \ +\ + if (_stack_->callbacks && _stack_->callbacks->read) \ + _stack_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _stack_) \ + { \ + return _stack_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _stack_) \ + { \ + return _stack_->count >= _stack_->capacity; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _stack_) \ + { \ + return _stack_->count; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _stack_) \ + { \ + return _stack_->capacity; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _stack_) \ + { \ + return _stack_->flag; \ + } \ +\ + bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity) \ + { \ + if (_stack_->capacity == capacity) \ + goto success; \ +\ + if (capacity < _stack_->count) \ + { \ + _stack_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + V *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(V) * capacity); \ +\ + if (!new_buffer) \ + { \ + _stack_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + /* TODO zero out new slots */ \ +\ + _stack_->buffer = new_buffer; \ + _stack_->capacity = capacity; \ +\ + success: \ +\ + _stack_->flag = CMC_FLAG_OK; \ +\ + if (_stack_->callbacks && _stack_->callbacks->resize) \ + _stack_->callbacks->resize(); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)(_stack_->capacity, _stack_->f_val, _stack_->alloc, NULL); \ +\ + if (!result) \ + { \ + _stack_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_stack_, callbacks); \ +\ + if (_stack_->f_val->cpy) \ + { \ + for (size_t i = 0; i < _stack_->count; i++) \ + result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); \ + } \ + else \ + memcpy(result->buffer, _stack_->buffer, sizeof(V) * _stack_->count); \ +\ + result->count = _stack_->count; \ +\ + _stack_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_) \ - { \ - _stack1_->flag = CMC_FLAG_OK; \ - _stack2_->flag = CMC_FLAG_OK; \ - \ - if (_stack1_->count != _stack2_->count) \ - return false; \ - \ - for (size_t i = 0; i < _stack1_->count; i++) \ - { \ - if (_stack1_->f_val->cmp(_stack1_->buffer[i], \ - _stack2_->buffer[i]) != 0) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _stack_) \ - { \ - struct cmc_string str; \ - struct SNAME *s_ = _stack_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_stack, \ - #SNAME, #V, s_, s_->buffer, s_->capacity, s_->count, \ - s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - { \ - if (!_stack_->f_val->str(fptr, _stack_->buffer[i])) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_advance)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_rewind)(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return 0; \ - \ - return iter->target->count - 1 - iter->cursor; \ + { \ + _stack1_->flag = CMC_FLAG_OK; \ + _stack2_->flag = CMC_FLAG_OK; \ +\ + if (_stack1_->count != _stack2_->count) \ + return false; \ +\ + for (size_t i = 0; i < _stack1_->count; i++) \ + { \ + if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _stack_) \ + { \ + struct cmc_string str; \ + struct SNAME *s_ = _stack_; \ +\ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_stack, #SNAME, #V, s_, s_->buffer, s_->capacity, \ + s_->count, s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ +\ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr) \ + { \ + for (size_t i = 0; i < _stack_->count; i++) \ + { \ + if (!_stack_->f_val->str(fptr, _stack_->buffer[i])) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->count - 1; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor--; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor++; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor < steps) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor += steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_advance)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_rewind)(iter, index - iter->cursor); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->target->buffer[iter->cursor]); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return 0; \ +\ + return iter->target->count - 1 - iter->cursor; \ } #endif /* CMC_CMC_STACK_H */ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index c064d31..0591e3b 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -41,1265 +41,1206 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " /** * Core TreeMap implementation */ -#define CMC_CMC_TREEMAP_CORE(PARAMS) \ +#define CMC_CMC_TREEMAP_CORE(PARAMS) \ CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \ CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) -#define CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \ - CMC_CMC_TREEMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ +#define CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \ + CMC_CMC_TREEMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) -#define CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_TREEMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ +#define CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) \ + CMC_CMC_TREEMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREEMAP_CORE_HEADER_(PFX, SNAME, K, V) \ - \ - /* Treemap Structure */ \ - struct SNAME \ - { \ - /* Root node */ \ - struct CMC_DEF_NODE(SNAME) * root; \ - \ - /* Current amount of keys */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Treemap Node */ \ - struct CMC_DEF_NODE(SNAME) \ - { \ - /* Node Key */ \ - K key; \ - \ - /* Node Value */ \ - V value; \ - \ - /* Node height used by the AVL tree to keep it strictly balanced */ \ - unsigned char height; \ - \ - /* Right child node or subtree */ \ - struct CMC_DEF_NODE(SNAME) * right; \ - \ - /* Left child node or subtree */ \ - struct CMC_DEF_NODE(SNAME) * left; \ - \ - /* Parent node */ \ - struct CMC_DEF_NODE(SNAME) * parent; \ - }; \ - \ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(K); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(K); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(K); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(K); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(K); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(K); \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Treemap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target treemap */ \ - struct SNAME *target; \ - \ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ - \ - /* The first node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * first; \ - \ - /* The last node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * last; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ - V * old_value); \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ +#define CMC_CMC_TREEMAP_CORE_HEADER_(PFX, SNAME, K, V) \ +\ + /* Treemap Structure */ \ + struct SNAME \ + { \ + /* Root node */ \ + struct CMC_DEF_NODE(SNAME) * root; \ +\ + /* Current amount of keys */ \ + size_t count; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Key function table */ \ + struct CMC_DEF_FKEY(SNAME) * f_key; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Treemap Node */ \ + struct CMC_DEF_NODE(SNAME) \ + { \ + /* Node Key */ \ + K key; \ +\ + /* Node Value */ \ + V value; \ +\ + /* Node height used by the AVL tree to keep it strictly balanced */ \ + unsigned char height; \ +\ + /* Right child node or subtree */ \ + struct CMC_DEF_NODE(SNAME) * right; \ +\ + /* Left child node or subtree */ \ + struct CMC_DEF_NODE(SNAME) * left; \ +\ + /* Parent node */ \ + struct CMC_DEF_NODE(SNAME) * parent; \ + }; \ +\ + /* Key struct function table */ \ + struct CMC_DEF_FKEY(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(K); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(K); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(K); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(K); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(K); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(K); \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Treemap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target treemap */ \ + struct SNAME *target; \ +\ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ +\ + /* The first node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * first; \ +\ + /* The last node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * last; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _map_); \ + void CMC_(PFX, _free)(struct SNAME * _map_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ + V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ + bool CMC_(PFX, _empty)(struct SNAME * _map_); \ + size_t CMC_(PFX, _count)(struct SNAME * _map_); \ + int CMC_(PFX, _flag)(struct SNAME * _map_); \ + /* Collection Utility */ \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ +\ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREEMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ - \ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value); \ - static struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key); \ - static unsigned char CMC_(PFX, \ - _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \ - static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * \ - node); \ - static void CMC_(PFX, \ - _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \ +#define CMC_CMC_TREEMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ +\ + /* Implementation Detail Functions */ \ + static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value); \ + static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key); \ + static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \ + static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node); \ + static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \ static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z); \ - static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, \ - struct CMC_DEF_NODE(SNAME) * node); \ - \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - if (!f_key || !f_val) \ - return NULL; \ - \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->count = 0; \ - _map_->root = NULL; \ - _map_->flag = CMC_FLAG_OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->alloc = alloc; \ - _map_->callbacks = NULL; \ - \ - return _map_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!f_key || !f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_map_) \ - return NULL; \ - \ - _map_->count = 0; \ - _map_->root = NULL; \ - _map_->flag = CMC_FLAG_OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->alloc = alloc; \ - _map_->callbacks = callbacks; \ - \ - return _map_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _map_) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ - struct CMC_DEF_NODE(SNAME) *up = NULL; \ - \ - while (scan != NULL) \ - { \ - if (scan->left != NULL) \ - { \ - struct CMC_DEF_NODE(SNAME) *left = scan->left; \ - \ - scan->left = up; \ - up = scan; \ - scan = left; \ - } \ - else if (scan->right != NULL) \ - { \ - struct CMC_DEF_NODE(SNAME) *right = scan->right; \ - \ - scan->left = up; \ - scan->right = NULL; \ - up = scan; \ - scan = right; \ - } \ - else \ - { \ - if (up == NULL) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ - \ - _map_->alloc->free(scan); \ - scan = NULL; \ - } \ - \ - while (up != NULL) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ - \ - _map_->alloc->free(scan); \ - \ - if (up->right != NULL) \ - { \ - scan = up->right; \ - up->right = NULL; \ - break; \ - } \ - else \ - { \ - scan = up; \ - up = up->left; \ - } \ - } \ - } \ - } \ - \ - _map_->count = 0; \ - _map_->root = NULL; \ - _map_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _map_) \ - { \ - CMC_(PFX, _clear)(_map_); \ - \ - _map_->alloc->free(_map_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _map_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ - \ - _map_->callbacks = callbacks; \ - \ - _map_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->root = CMC_(PFX, _impl_new_node)(_map_, key, value); \ - \ - if (!_map_->root) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - } \ - else \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ - struct CMC_DEF_NODE(SNAME) *parent = scan; \ - \ - while (scan != NULL) \ - { \ - parent = scan; \ - \ - if (_map_->f_key->cmp(scan->key, key) > 0) \ - scan = scan->left; \ - else if (_map_->f_key->cmp(scan->key, key) < 0) \ - scan = scan->right; \ - else \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * node; \ - \ - if (_map_->f_key->cmp(parent->key, key) > 0) \ - { \ - parent->left = CMC_(PFX, _impl_new_node)(_map_, key, value); \ - \ - if (!parent->left) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - parent->left->parent = parent; \ - node = parent->left; \ - } \ - else \ - { \ - parent->right = CMC_(PFX, _impl_new_node)(_map_, key, value); \ - \ - if (!parent->right) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - parent->right->parent = parent; \ - node = parent->right; \ - } \ - \ - CMC_(PFX, _impl_rebalance)(_map_, node); \ - } \ - \ - _map_->count++; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, \ - V * old_value) \ - { \ - struct CMC_DEF_NODE(SNAME) *node = \ - CMC_(PFX, _impl_get_node)(_map_, key); \ - \ - if (!node) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - if (old_value) \ - *old_value = node->value; \ - \ - node->value = new_value; \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *node = \ - CMC_(PFX, _impl_get_node)(_map_, key); \ - \ - if (!node) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - if (out_value) \ - *out_value = node->value; \ - \ - struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \ - \ - bool is_root = node->parent == NULL; \ - \ - if (node->left == NULL && node->right == NULL) \ - { \ - if (is_root) \ - _map_->root = NULL; \ - else \ - { \ - unbalanced = node->parent; \ - \ - if (node->parent->right == node) \ - node->parent->right = NULL; \ - else \ - node->parent->left = NULL; \ - } \ - \ - _map_->alloc->free(node); \ - } \ - else if (node->left == NULL) \ - { \ - if (is_root) \ - { \ - _map_->root = node->right; \ - _map_->root->parent = NULL; \ - } \ - else \ - { \ - unbalanced = node->parent; \ - \ - node->right->parent = node->parent; \ - \ - if (node->parent->right == node) \ - node->parent->right = node->right; \ - else \ - node->parent->left = node->right; \ - } \ - \ - _map_->alloc->free(node); \ - } \ - else if (node->right == NULL) \ - { \ - if (is_root) \ - { \ - _map_->root = node->left; \ - _map_->root->parent = NULL; \ - } \ - else \ - { \ - unbalanced = node->parent; \ - \ - node->left->parent = node->parent; \ - \ - if (node->parent->right == node) \ - node->parent->right = node->left; \ - else \ - node->parent->left = node->left; \ - } \ - \ - _map_->alloc->free(node); \ - } \ - else \ - { \ - temp = node->right; \ - while (temp->left != NULL) \ - temp = temp->left; \ - \ - K temp_key = temp->key; \ - V temp_val = temp->value; \ - \ - unbalanced = temp->parent; \ - \ - if (temp->left == NULL && temp->right == NULL) \ - { \ - if (temp->parent->right == temp) \ - temp->parent->right = NULL; \ - else \ - temp->parent->left = NULL; \ - } \ - else if (temp->left == NULL) \ - { \ - temp->right->parent = temp->parent; \ - \ - if (temp->parent->right == temp) \ - temp->parent->right = temp->right; \ - else \ - temp->parent->left = temp->right; \ - } \ - else if (temp->right == NULL) \ - { \ - temp->left->parent = temp->parent; \ - \ - if (temp->parent->right == temp) \ - temp->parent->right = temp->left; \ - else \ - temp->parent->left = temp->left; \ - } \ - \ - _map_->alloc->free(temp); \ - \ - node->key = temp_key; \ - node->value = temp_val; \ - } \ - \ - if (unbalanced != NULL) \ - CMC_(PFX, _impl_rebalance)(_map_, unbalanced); \ - \ - if (_map_->count == 0) \ - _map_->root = NULL; \ - \ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ - \ - while (scan->right != NULL) \ - scan = scan->right; \ - \ - if (key) \ - *key = scan->key; \ - if (value) \ - *value = scan->value; \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ - \ - while (scan->left != NULL) \ - scan = scan->left; \ - \ - if (key) \ - *key = scan->key; \ - if (value) \ - *value = scan->value; \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *node = \ - CMC_(PFX, _impl_get_node)(_map_, key); \ - \ - if (!node) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return node->value; \ - } \ - \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *node = \ - CMC_(PFX, _impl_get_node)(_map_, key); \ - \ - if (!node) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return NULL; \ - } \ - \ - _map_->flag = CMC_FLAG_OK; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return &(node->value); \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ - { \ - bool result = CMC_(PFX, _impl_get_node)(_map_, key) != NULL; \ - \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _map_) \ - { \ - return _map_->count == 0; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _map_) \ - { \ - return _map_->count; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _map_) \ - { \ - return _map_->flag; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ - { \ - /* Callback will be added later */ \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ - \ - if (!result) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - /* TODO turn this into a normal loop */ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (_map_->f_key->cpy) \ - key = _map_->f_key->cpy(key); \ - if (_map_->f_val->cpy) \ - value = _map_->f_val->cpy(value); \ - \ - /* TODO check this for errors */ \ - CMC_(PFX, _insert)(result, key, value); \ - } \ - \ - result->callbacks = _map_->callbacks; \ - _map_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ - { \ - _map1_->flag = CMC_FLAG_OK; \ - _map2_->flag = CMC_FLAG_OK; \ - \ - if (_map1_->count != _map2_->count) \ - return false; \ - \ - /* TODO turn this into a normal loop */ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)( \ - _map2_, CMC_(PFX, _iter_key)(&iter)); \ - \ - if (node == NULL) \ - return false; \ - \ - if (_map1_->f_val->cmp(node->value, \ - CMC_(PFX, _iter_value)(&iter)) != 0) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treemap, \ - #SNAME, #K, #V, m_, m_->root, m_->count, m_->flag, \ - m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = _map_->root; \ - \ - bool left_done = false; \ - \ - while (root) \ - { \ - if (!left_done) \ - { \ - while (root->left) \ - root = root->left; \ - } \ - \ - if (!_map_->f_key->str(fptr, root->key) && \ - !_map_->f_val->str(fptr, root->value)) \ - return false; \ - \ - left_done = true; \ - \ - if (root->right) \ - { \ - left_done = false; \ - root = root->right; \ - } \ - else if (root->parent) \ - { \ - while (root->parent && root == root->parent->right) \ - root = root->parent; \ - \ - if (!root->parent) \ - break; \ - \ - root = root->parent; \ - } \ - else \ - break; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->left != NULL) \ - iter.cursor = iter.cursor->left; \ - \ - iter.first = iter.cursor; \ - \ - iter.last = target->root; \ - while (iter.last->right != NULL) \ - iter.last = iter.last->right; \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->right != NULL) \ - iter.cursor = iter.cursor->right; \ - \ - iter.last = iter.cursor; \ - \ - iter.first = target->root; \ - while (iter.first->left != NULL) \ - iter.first = iter.first->left; \ - \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->first; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->cursor = iter->last; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - if (iter->cursor->right != NULL) \ - { \ - iter->cursor = iter->cursor->right; \ - \ - while (iter->cursor->left != NULL) \ - iter->cursor = iter->cursor->left; \ - \ - iter->index++; \ - \ - return true; \ - } \ - \ - while (true) \ - { \ - if (iter->cursor->parent->left == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ - \ - iter->index++; \ - \ - return true; \ - } \ - \ - iter->cursor = iter->cursor->parent; \ - } \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - if (iter->cursor->left != NULL) \ - { \ - iter->cursor = iter->cursor->left; \ - \ - while (iter->cursor->right != NULL) \ - iter->cursor = iter->cursor->right; \ - \ - iter->index--; \ - \ - return true; \ - } \ - \ - while (true) \ - { \ - if (iter->cursor->parent->right == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ - \ - iter->index--; \ - \ - return true; \ - } \ - \ - iter->cursor = iter->cursor->parent; \ - } \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ - \ - return iter->cursor->key; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->cursor->value; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->cursor->value); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ - static struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *node = \ - _map_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ - \ - if (!node) \ - return NULL; \ - \ - node->key = key; \ - node->value = value; \ - node->right = NULL; \ - node->left = NULL; \ - node->parent = NULL; \ - node->height = 0; \ - \ - return node; \ - } \ - \ - static struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ - \ - while (scan != NULL) \ - { \ - if (_map_->f_key->cmp(scan->key, key) > 0) \ - scan = scan->left; \ - else if (_map_->f_key->cmp(scan->key, key) < 0) \ - scan = scan->right; \ - else \ - return scan; \ - } \ - \ - return NULL; \ - } \ - \ + static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, struct CMC_DEF_NODE(SNAME) * node); \ +\ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(f_key, f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!f_key || !f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_map_) \ + return NULL; \ +\ + _map_->count = 0; \ + _map_->root = NULL; \ + _map_->flag = CMC_FLAG_OK; \ + _map_->f_key = f_key; \ + _map_->f_val = f_val; \ + _map_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ +\ + return _map_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _map_) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ + struct CMC_DEF_NODE(SNAME) *up = NULL; \ +\ + while (scan != NULL) \ + { \ + if (scan->left != NULL) \ + { \ + struct CMC_DEF_NODE(SNAME) *left = scan->left; \ +\ + scan->left = up; \ + up = scan; \ + scan = left; \ + } \ + else if (scan->right != NULL) \ + { \ + struct CMC_DEF_NODE(SNAME) *right = scan->right; \ +\ + scan->left = up; \ + scan->right = NULL; \ + up = scan; \ + scan = right; \ + } \ + else \ + { \ + if (up == NULL) \ + { \ + if (_map_->f_key->free) \ + _map_->f_key->free(scan->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(scan->value); \ +\ + _map_->alloc->free(scan); \ + scan = NULL; \ + } \ +\ + while (up != NULL) \ + { \ + if (_map_->f_key->free) \ + _map_->f_key->free(scan->key); \ + if (_map_->f_val->free) \ + _map_->f_val->free(scan->value); \ +\ + _map_->alloc->free(scan); \ +\ + if (up->right != NULL) \ + { \ + scan = up->right; \ + up->right = NULL; \ + break; \ + } \ + else \ + { \ + scan = up; \ + up = up->left; \ + } \ + } \ + } \ + } \ +\ + _map_->count = 0; \ + _map_->root = NULL; \ + _map_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _map_) \ + { \ + CMC_(PFX, _clear)(_map_); \ +\ + _map_->alloc->free(_map_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _map_->alloc = &cmc_alloc_node_default; \ + else \ + _map_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ +\ + _map_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->root = CMC_(PFX, _impl_new_node)(_map_, key, value); \ +\ + if (!_map_->root) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ + } \ + else \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ + struct CMC_DEF_NODE(SNAME) *parent = scan; \ +\ + while (scan != NULL) \ + { \ + parent = scan; \ +\ + if (_map_->f_key->cmp(scan->key, key) > 0) \ + scan = scan->left; \ + else if (_map_->f_key->cmp(scan->key, key) < 0) \ + scan = scan->right; \ + else \ + { \ + _map_->flag = CMC_FLAG_DUPLICATE; \ + return false; \ + } \ + } \ +\ + struct CMC_DEF_NODE(SNAME) * node; \ +\ + if (_map_->f_key->cmp(parent->key, key) > 0) \ + { \ + parent->left = CMC_(PFX, _impl_new_node)(_map_, key, value); \ +\ + if (!parent->left) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + parent->left->parent = parent; \ + node = parent->left; \ + } \ + else \ + { \ + parent->right = CMC_(PFX, _impl_new_node)(_map_, key, value); \ +\ + if (!parent->right) \ + { \ + _map_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + parent->right->parent = parent; \ + node = parent->right; \ + } \ +\ + CMC_(PFX, _impl_rebalance)(_map_, node); \ + } \ +\ + _map_->count++; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->create) \ + _map_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \ + { \ + struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ +\ + if (!node) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + if (old_value) \ + *old_value = node->value; \ +\ + node->value = new_value; \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->update) \ + _map_->callbacks->update(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ +\ + if (!node) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + if (out_value) \ + *out_value = node->value; \ +\ + struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \ +\ + bool is_root = node->parent == NULL; \ +\ + if (node->left == NULL && node->right == NULL) \ + { \ + if (is_root) \ + _map_->root = NULL; \ + else \ + { \ + unbalanced = node->parent; \ +\ + if (node->parent->right == node) \ + node->parent->right = NULL; \ + else \ + node->parent->left = NULL; \ + } \ +\ + _map_->alloc->free(node); \ + } \ + else if (node->left == NULL) \ + { \ + if (is_root) \ + { \ + _map_->root = node->right; \ + _map_->root->parent = NULL; \ + } \ + else \ + { \ + unbalanced = node->parent; \ +\ + node->right->parent = node->parent; \ +\ + if (node->parent->right == node) \ + node->parent->right = node->right; \ + else \ + node->parent->left = node->right; \ + } \ +\ + _map_->alloc->free(node); \ + } \ + else if (node->right == NULL) \ + { \ + if (is_root) \ + { \ + _map_->root = node->left; \ + _map_->root->parent = NULL; \ + } \ + else \ + { \ + unbalanced = node->parent; \ +\ + node->left->parent = node->parent; \ +\ + if (node->parent->right == node) \ + node->parent->right = node->left; \ + else \ + node->parent->left = node->left; \ + } \ +\ + _map_->alloc->free(node); \ + } \ + else \ + { \ + temp = node->right; \ + while (temp->left != NULL) \ + temp = temp->left; \ +\ + K temp_key = temp->key; \ + V temp_val = temp->value; \ +\ + unbalanced = temp->parent; \ +\ + if (temp->left == NULL && temp->right == NULL) \ + { \ + if (temp->parent->right == temp) \ + temp->parent->right = NULL; \ + else \ + temp->parent->left = NULL; \ + } \ + else if (temp->left == NULL) \ + { \ + temp->right->parent = temp->parent; \ +\ + if (temp->parent->right == temp) \ + temp->parent->right = temp->right; \ + else \ + temp->parent->left = temp->right; \ + } \ + else if (temp->right == NULL) \ + { \ + temp->left->parent = temp->parent; \ +\ + if (temp->parent->right == temp) \ + temp->parent->right = temp->left; \ + else \ + temp->parent->left = temp->left; \ + } \ +\ + _map_->alloc->free(temp); \ +\ + node->key = temp_key; \ + node->value = temp_val; \ + } \ +\ + if (unbalanced != NULL) \ + CMC_(PFX, _impl_rebalance)(_map_, unbalanced); \ +\ + if (_map_->count == 0) \ + _map_->root = NULL; \ +\ + _map_->count--; \ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->delete) \ + _map_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ +\ + while (scan->right != NULL) \ + scan = scan->right; \ +\ + if (key) \ + *key = scan->key; \ + if (value) \ + *value = scan->value; \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ +\ + while (scan->left != NULL) \ + scan = scan->left; \ +\ + if (key) \ + *key = scan->key; \ + if (value) \ + *value = scan->value; \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ +\ + if (!node) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return (V){ 0 }; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return node->value; \ + } \ +\ + V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ + { \ + if (CMC_(PFX, _empty)(_map_)) \ + { \ + _map_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ +\ + if (!node) \ + { \ + _map_->flag = CMC_FLAG_NOT_FOUND; \ + return NULL; \ + } \ +\ + _map_->flag = CMC_FLAG_OK; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return &(node->value); \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ + { \ + bool result = CMC_(PFX, _impl_get_node)(_map_, key) != NULL; \ +\ + if (_map_->callbacks && _map_->callbacks->read) \ + _map_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _map_) \ + { \ + return _map_->count == 0; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _map_) \ + { \ + return _map_->count; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _map_) \ + { \ + return _map_->flag; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ + { \ + /* Callback will be added later */ \ + struct SNAME *result = CMC_(PFX, _new_custom)(_map_->f_key, _map_->f_val, _map_->alloc, NULL); \ +\ + if (!result) \ + { \ + _map_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + /* TODO turn this into a normal loop */ \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + K key = CMC_(PFX, _iter_key)(&iter); \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (_map_->f_key->cpy) \ + key = _map_->f_key->cpy(key); \ + if (_map_->f_val->cpy) \ + value = _map_->f_val->cpy(value); \ +\ + /* TODO check this for errors */ \ + CMC_(PFX, _insert)(result, key, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ + _map_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ + { \ + _map1_->flag = CMC_FLAG_OK; \ + _map2_->flag = CMC_FLAG_OK; \ +\ + if (_map1_->count != _map2_->count) \ + return false; \ +\ + /* TODO turn this into a normal loop */ \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map2_, CMC_(PFX, _iter_key)(&iter)); \ +\ + if (node == NULL) \ + return false; \ +\ + if (_map1_->f_val->cmp(node->value, CMC_(PFX, _iter_value)(&iter)) != 0) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ + { \ + struct cmc_string str; \ + struct SNAME *m_ = _map_; \ +\ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treemap, #SNAME, #K, #V, m_, m_->root, m_->count, \ + m_->flag, m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ +\ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ + { \ + struct CMC_DEF_NODE(SNAME) *root = _map_->root; \ +\ + bool left_done = false; \ +\ + while (root) \ + { \ + if (!left_done) \ + { \ + while (root->left) \ + root = root->left; \ + } \ +\ + if (!_map_->f_key->str(fptr, root->key) && !_map_->f_val->str(fptr, root->value)) \ + return false; \ +\ + left_done = true; \ +\ + if (root->right) \ + { \ + left_done = false; \ + root = root->right; \ + } \ + else if (root->parent) \ + { \ + while (root->parent && root == root->parent->right) \ + root = root->parent; \ +\ + if (!root->parent) \ + break; \ +\ + root = root->parent; \ + } \ + else \ + break; \ + } \ +\ + return true; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->left != NULL) \ + iter.cursor = iter.cursor->left; \ +\ + iter.first = iter.cursor; \ +\ + iter.last = target->root; \ + while (iter.last->right != NULL) \ + iter.last = iter.last->right; \ + } \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->right != NULL) \ + iter.cursor = iter.cursor->right; \ +\ + iter.last = iter.cursor; \ +\ + iter.first = target->root; \ + while (iter.first->left != NULL) \ + iter.first = iter.first->left; \ +\ + iter.index = target->count - 1; \ + } \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->first; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + iter->cursor = iter->last; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->right != NULL) \ + { \ + iter->cursor = iter->cursor->right; \ +\ + while (iter->cursor->left != NULL) \ + iter->cursor = iter->cursor->left; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->left == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->left != NULL) \ + { \ + iter->cursor = iter->cursor->left; \ +\ + while (iter->cursor->right != NULL) \ + iter->cursor = iter->cursor->right; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->right == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (K){ 0 }; \ +\ + return iter->cursor->key; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->cursor->value; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->cursor->value); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } \ +\ + static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *node = _map_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ +\ + if (!node) \ + return NULL; \ +\ + node->key = key; \ + node->value = value; \ + node->right = NULL; \ + node->left = NULL; \ + node->parent = NULL; \ + node->height = 0; \ +\ + return node; \ + } \ +\ + static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ +\ + while (scan != NULL) \ + { \ + if (_map_->f_key->cmp(scan->key, key) > 0) \ + scan = scan->left; \ + else if (_map_->f_key->cmp(scan->key, key) < 0) \ + scan = scan->right; \ + else \ + return scan; \ + } \ +\ + return NULL; \ + } \ +\ static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node) \ - { \ - if (node == NULL) \ - return 0; \ - \ - return node->height; \ - } \ - \ - static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * \ - node) \ - { \ - if (node == NULL) \ - return 0; \ - \ - unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \ - unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \ - \ - return 1 + (h_l > h_r ? h_l : h_r); \ - } \ - \ + { \ + if (node == NULL) \ + return 0; \ +\ + return node->height; \ + } \ +\ + static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node) \ + { \ + if (node == NULL) \ + return 0; \ +\ + unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \ + unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \ +\ + return 1 + (h_l > h_r ? h_l : h_r); \ + } \ +\ static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = *Z; \ - struct CMC_DEF_NODE(SNAME) *new_root = root->left; \ - \ - if (root->parent != NULL) \ - { \ - if (root->parent->left == root) \ - root->parent->left = new_root; \ - else \ - root->parent->right = new_root; \ - } \ - \ - new_root->parent = root->parent; \ - \ - root->parent = new_root; \ - root->left = new_root->right; \ - \ - if (root->left) \ - root->left->parent = root; \ - \ - new_root->right = root; \ - \ - root->height = CMC_(PFX, _impl_hupdate)(root); \ - new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ - \ - *Z = new_root; \ - } \ - \ - static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = *Z; \ - struct CMC_DEF_NODE(SNAME) *new_root = root->right; \ - \ - if (root->parent != NULL) \ - { \ - if (root->parent->right == root) \ - root->parent->right = new_root; \ - else \ - root->parent->left = new_root; \ - } \ - \ - new_root->parent = root->parent; \ - \ - root->parent = new_root; \ - root->right = new_root->left; \ - \ - if (root->right) \ - root->right->parent = root; \ - \ - new_root->left = root; \ - \ - root->height = CMC_(PFX, _impl_hupdate)(root); \ - new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ - \ - *Z = new_root; \ - } \ - \ - static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, \ - struct CMC_DEF_NODE(SNAME) * node) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \ - \ - int balance; \ - bool is_root = false; \ - \ - while (scan != NULL) \ - { \ - if (scan->parent == NULL) \ - is_root = true; \ - \ - scan->height = CMC_(PFX, _impl_hupdate)(scan); \ - balance = CMC_(PFX, _impl_h)(scan->right) - \ - CMC_(PFX, _impl_h)(scan->left); \ - \ - if (balance >= 2) \ - { \ - child = scan->right; \ - \ - if (CMC_(PFX, _impl_h)(child->right) < \ - CMC_(PFX, _impl_h)(child->left)) \ - CMC_(PFX, _impl_rotate_right)(&(scan->right)); \ - \ - CMC_(PFX, _impl_rotate_left)(&scan); \ - } \ - else if (balance <= -2) \ - { \ - child = scan->left; \ - \ - if (CMC_(PFX, _impl_h)(child->left) < \ - CMC_(PFX, _impl_h)(child->right)) \ - CMC_(PFX, _impl_rotate_left)(&(scan->left)); \ - \ - CMC_(PFX, _impl_rotate_right)(&scan); \ - } \ - \ - if (is_root) \ - { \ - _map_->root = scan; \ - is_root = false; \ - } \ - \ - scan = scan->parent; \ - } \ + { \ + struct CMC_DEF_NODE(SNAME) *root = *Z; \ + struct CMC_DEF_NODE(SNAME) *new_root = root->left; \ +\ + if (root->parent != NULL) \ + { \ + if (root->parent->left == root) \ + root->parent->left = new_root; \ + else \ + root->parent->right = new_root; \ + } \ +\ + new_root->parent = root->parent; \ +\ + root->parent = new_root; \ + root->left = new_root->right; \ +\ + if (root->left) \ + root->left->parent = root; \ +\ + new_root->right = root; \ +\ + root->height = CMC_(PFX, _impl_hupdate)(root); \ + new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ +\ + *Z = new_root; \ + } \ +\ + static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \ + { \ + struct CMC_DEF_NODE(SNAME) *root = *Z; \ + struct CMC_DEF_NODE(SNAME) *new_root = root->right; \ +\ + if (root->parent != NULL) \ + { \ + if (root->parent->right == root) \ + root->parent->right = new_root; \ + else \ + root->parent->left = new_root; \ + } \ +\ + new_root->parent = root->parent; \ +\ + root->parent = new_root; \ + root->right = new_root->left; \ +\ + if (root->right) \ + root->right->parent = root; \ +\ + new_root->left = root; \ +\ + root->height = CMC_(PFX, _impl_hupdate)(root); \ + new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ +\ + *Z = new_root; \ + } \ +\ + static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, struct CMC_DEF_NODE(SNAME) * node) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \ +\ + int balance; \ + bool is_root = false; \ +\ + while (scan != NULL) \ + { \ + if (scan->parent == NULL) \ + is_root = true; \ +\ + scan->height = CMC_(PFX, _impl_hupdate)(scan); \ + balance = CMC_(PFX, _impl_h)(scan->right) - CMC_(PFX, _impl_h)(scan->left); \ +\ + if (balance >= 2) \ + { \ + child = scan->right; \ +\ + if (CMC_(PFX, _impl_h)(child->right) < CMC_(PFX, _impl_h)(child->left)) \ + CMC_(PFX, _impl_rotate_right)(&(scan->right)); \ +\ + CMC_(PFX, _impl_rotate_left)(&scan); \ + } \ + else if (balance <= -2) \ + { \ + child = scan->left; \ +\ + if (CMC_(PFX, _impl_h)(child->left) < CMC_(PFX, _impl_h)(child->right)) \ + CMC_(PFX, _impl_rotate_left)(&(scan->left)); \ +\ + CMC_(PFX, _impl_rotate_right)(&scan); \ + } \ +\ + if (is_root) \ + { \ + _map_->root = scan; \ + is_root = false; \ + } \ +\ + scan = scan->parent; \ + } \ } #endif /* CMC_CMC_TREEMAP_H */ diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 589e07c..6684f0a 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -40,1348 +40,1285 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " /** * Core TreeSet implementation */ -#define CMC_CMC_TREESET_CORE(PARAMS) \ +#define CMC_CMC_TREESET_CORE(PARAMS) \ CMC_CMC_TREESET_CORE_HEADER(PARAMS) \ CMC_CMC_TREESET_CORE_SOURCE(PARAMS) -#define CMC_CMC_TREESET_CORE_HEADER(PARAMS) \ - CMC_CMC_TREESET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_CMC_TREESET_CORE_HEADER(PARAMS) \ + CMC_CMC_TREESET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_CMC_TREESET_CORE_SOURCE(PARAMS) \ - CMC_CMC_TREESET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_CMC_TREESET_CORE_SOURCE(PARAMS) \ + CMC_CMC_TREESET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- * Header * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREESET_CORE_HEADER_(PFX, SNAME, V) \ - \ - /* Treeset Structure */ \ - struct SNAME \ - { \ - /* Root node */ \ - struct CMC_DEF_NODE(SNAME) * root; \ - \ - /* Current amount of elements */ \ - size_t count; \ - \ - /* Flags indicating errors or success */ \ - int flag; \ - \ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ - \ - /* Custom allocation functions */ \ - struct cmc_alloc_node *alloc; \ - \ - /* Custom callback functions */ \ - struct cmc_callbacks *callbacks; \ - }; \ - \ - /* Treeset Node */ \ - struct CMC_DEF_NODE(SNAME) \ - { \ - /* Node element */ \ - V value; \ - \ - /* Node height used by the AVL tree to keep it strictly balanced */ \ - unsigned char height; \ - \ - /* Right child node or subtree */ \ - struct CMC_DEF_NODE(SNAME) * right; \ - \ - /* Left child node or subtree */ \ - struct CMC_DEF_NODE(SNAME) * left; \ - \ - /* Parent node */ \ - struct CMC_DEF_NODE(SNAME) * parent; \ - }; \ - \ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ - \ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ - \ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ - \ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ - \ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ - \ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ - \ - /* Treeset Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target treeset */ \ - struct SNAME *target; \ - \ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ - \ - /* The first node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * first; \ - \ - /* The last node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * last; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _set_); \ - void CMC_(PFX, _free)(struct SNAME * _set_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _set_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _set_); \ - size_t CMC_(PFX, _count)(struct SNAME * _set_); \ - int CMC_(PFX, _flag)(struct SNAME * _set_); \ - /* Collection Utility */ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \ - \ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ +#define CMC_CMC_TREESET_CORE_HEADER_(PFX, SNAME, V) \ +\ + /* Treeset Structure */ \ + struct SNAME \ + { \ + /* Root node */ \ + struct CMC_DEF_NODE(SNAME) * root; \ +\ + /* Current amount of elements */ \ + size_t count; \ +\ + /* Flags indicating errors or success */ \ + int flag; \ +\ + /* Value function table */ \ + struct CMC_DEF_FVAL(SNAME) * f_val; \ +\ + /* Custom allocation functions */ \ + struct CMC_ALLOC_NODE_NAME *alloc; \ +\ + /* Custom callback functions */ \ + CMC_CALLBACKS_DECL; \ + }; \ +\ + /* Treeset Node */ \ + struct CMC_DEF_NODE(SNAME) \ + { \ + /* Node element */ \ + V value; \ +\ + /* Node height used by the AVL tree to keep it strictly balanced */ \ + unsigned char height; \ +\ + /* Right child node or subtree */ \ + struct CMC_DEF_NODE(SNAME) * right; \ +\ + /* Left child node or subtree */ \ + struct CMC_DEF_NODE(SNAME) * left; \ +\ + /* Parent node */ \ + struct CMC_DEF_NODE(SNAME) * parent; \ + }; \ +\ + /* Value struct function table */ \ + struct CMC_DEF_FVAL(SNAME) \ + { \ + /* Comparator function */ \ + CMC_DEF_FTAB_CMP(V); \ +\ + /* Copy function */ \ + CMC_DEF_FTAB_CPY(V); \ +\ + /* To string function */ \ + CMC_DEF_FTAB_STR(V); \ +\ + /* Free from memory function */ \ + CMC_DEF_FTAB_FREE(V); \ +\ + /* Hash function */ \ + CMC_DEF_FTAB_HASH(V); \ +\ + /* Priority function */ \ + CMC_DEF_FTAB_PRI(V); \ + }; \ +\ + /* Treeset Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target treeset */ \ + struct SNAME *target; \ +\ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ +\ + /* The first node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * first; \ +\ + /* The last node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * last; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Collection Functions */ \ + /* Collection Allocation and Deallocation */ \ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + void CMC_(PFX, _clear)(struct SNAME * _set_); \ + void CMC_(PFX, _free)(struct SNAME * _set_); \ + /* Customization of Allocation and Callbacks */ \ + void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ + /* Collection Input and Output */ \ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ + /* Element Access */ \ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ + /* Collection State */ \ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ + bool CMC_(PFX, _empty)(struct SNAME * _set_); \ + size_t CMC_(PFX, _count)(struct SNAME * _set_); \ + int CMC_(PFX, _flag)(struct SNAME * _set_); \ + /* Collection Utility */ \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \ +\ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - \ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_); \ +\ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ - \ - /* Default Value */ \ - static inline V CMC_(PFX, _impl_default_value)(void) \ - { \ - V _empty_value_; \ - \ - memset(&_empty_value_, 0, sizeof(V)); \ - \ - return _empty_value_; \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ +\ + /* Default Value */ \ + static inline V CMC_(PFX, _impl_default_value)(void) \ + { \ + V _empty_value_; \ +\ + memset(&_empty_value_, 0, sizeof(V)); \ +\ + return _empty_value_; \ } /* ------------------------------------------------------------------------- * Source * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREESET_CORE_SOURCE_(PFX, SNAME, V) \ - \ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value); \ - static struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value); \ - static unsigned char CMC_(PFX, \ - _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \ - static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * \ - node); \ - static void CMC_(PFX, \ - _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \ +#define CMC_CMC_TREESET_CORE_SOURCE_(PFX, SNAME, V) \ +\ + /* Implementation Detail Functions */ \ + static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value); \ + static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value); \ + static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \ + static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node); \ + static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \ static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z); \ - static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, \ - struct CMC_DEF_NODE(SNAME) * node); \ - \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - if (!f_val) \ - return NULL; \ - \ - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_set_) \ - return NULL; \ - \ - _set_->count = 0; \ - _set_->root = NULL; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - _set_->callbacks = NULL; \ - \ - return _set_; \ - } \ - \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!f_val) \ - return NULL; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ - \ - if (!_set_) \ - return NULL; \ - \ - _set_->count = 0; \ - _set_->root = NULL; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - _set_->callbacks = callbacks; \ - \ - return _set_; \ - } \ - \ - void CMC_(PFX, _clear)(struct SNAME * _set_) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ - struct CMC_DEF_NODE(SNAME) *up = NULL; \ - \ - while (scan != NULL) \ - { \ - if (scan->left != NULL) \ - { \ - struct CMC_DEF_NODE(SNAME) *left = scan->left; \ - \ - scan->left = up; \ - up = scan; \ - scan = left; \ - } \ - else if (scan->right != NULL) \ - { \ - struct CMC_DEF_NODE(SNAME) *right = scan->right; \ - \ - scan->left = up; \ - scan->right = NULL; \ - up = scan; \ - scan = right; \ - } \ - else \ - { \ - if (up == NULL) \ - { \ - if (_set_->f_val->free) \ - _set_->f_val->free(scan->value); \ - \ - _set_->alloc->free(scan); \ - scan = NULL; \ - } \ - \ - while (up != NULL) \ - { \ - if (_set_->f_val->free) \ - _set_->f_val->free(scan->value); \ - \ - _set_->alloc->free(scan); \ - \ - if (up->right != NULL) \ - { \ - scan = up->right; \ - up->right = NULL; \ - break; \ - } \ - else \ - { \ - scan = up; \ - up = up->left; \ - } \ - } \ - } \ - } \ - \ - _set_->count = 0; \ - _set_->root = NULL; \ - _set_->flag = CMC_FLAG_OK; \ - } \ - \ - void CMC_(PFX, _free)(struct SNAME * _set_) \ - { \ - CMC_(PFX, _clear)(_set_); \ - \ - _set_->alloc->free(_set_); \ - } \ - \ - void CMC_(PFX, _customize)(struct SNAME * _set_, \ - struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks) \ - { \ - if (!alloc) \ - _set_->alloc = &cmc_alloc_node_default; \ - else \ - _set_->alloc = alloc; \ - \ - _set_->callbacks = callbacks; \ - \ - _set_->flag = CMC_FLAG_OK; \ - } \ - \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->root = CMC_(PFX, _impl_new_node)(_set_, value); \ - \ - if (!_set_->root) \ - { \ - _set_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - } \ - else \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ - struct CMC_DEF_NODE(SNAME) *parent = scan; \ - \ - while (scan != NULL) \ - { \ - parent = scan; \ - \ - if (_set_->f_val->cmp(scan->value, value) > 0) \ - scan = scan->left; \ - else if (_set_->f_val->cmp(scan->value, value) < 0) \ - scan = scan->right; \ - else \ - { \ - _set_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * node; \ - \ - if (_set_->f_val->cmp(parent->value, value) > 0) \ - { \ - parent->left = CMC_(PFX, _impl_new_node)(_set_, value); \ - \ - if (!parent->left) \ - { \ - _set_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - parent->left->parent = parent; \ - node = parent->left; \ - } \ - else \ - { \ - parent->right = CMC_(PFX, _impl_new_node)(_set_, value); \ - \ - if (!parent->right) \ - { \ - _set_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - \ - parent->right->parent = parent; \ - node = parent->right; \ - } \ - \ - CMC_(PFX, _impl_rebalance)(_set_, node); \ - } \ - \ - _set_->count++; \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->create) \ - _set_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *node = \ - CMC_(PFX, _impl_get_node)(_set_, value); \ - \ - if (!node) \ - { \ - _set_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \ - \ - bool is_root = node->parent == NULL; \ - \ - if (node->left == NULL && node->right == NULL) \ - { \ - if (is_root) \ - _set_->root = NULL; \ - else \ - { \ - unbalanced = node->parent; \ - \ - if (node->parent->right == node) \ - node->parent->right = NULL; \ - else \ - node->parent->left = NULL; \ - } \ - \ - _set_->alloc->free(node); \ - } \ - else if (node->left == NULL) \ - { \ - if (is_root) \ - { \ - _set_->root = node->right; \ - _set_->root->parent = NULL; \ - } \ - else \ - { \ - unbalanced = node->parent; \ - \ - node->right->parent = node->parent; \ - \ - if (node->parent->right == node) \ - node->parent->right = node->right; \ - else \ - node->parent->left = node->right; \ - } \ - \ - _set_->alloc->free(node); \ - } \ - else if (node->right == NULL) \ - { \ - if (is_root) \ - { \ - _set_->root = node->left; \ - _set_->root->parent = NULL; \ - } \ - else \ - { \ - unbalanced = node->parent; \ - \ - node->left->parent = node->parent; \ - \ - if (node->parent->right == node) \ - node->parent->right = node->left; \ - else \ - node->parent->left = node->left; \ - } \ - \ - _set_->alloc->free(node); \ - } \ - else \ - { \ - temp = node->right; \ - while (temp->left != NULL) \ - temp = temp->left; \ - \ - V temp_value = temp->value; \ - \ - unbalanced = temp->parent; \ - \ - if (temp->left == NULL && temp->right == NULL) \ - { \ - if (temp->parent->right == temp) \ - temp->parent->right = NULL; \ - else \ - temp->parent->left = NULL; \ - } \ - else if (temp->left == NULL) \ - { \ - temp->right->parent = temp->parent; \ - \ - if (temp->parent->right == temp) \ - temp->parent->right = temp->right; \ - else \ - temp->parent->left = temp->right; \ - } \ - else if (temp->right == NULL) \ - { \ - temp->left->parent = temp->parent; \ - \ - if (temp->parent->right == temp) \ - temp->parent->right = temp->left; \ - else \ - temp->parent->left = temp->left; \ - } \ - \ - _set_->alloc->free(temp); \ - \ - node->value = temp_value; \ - } \ - \ - if (unbalanced != NULL) \ - CMC_(PFX, _impl_rebalance)(_set_, unbalanced); \ - \ - if (_set_->count == 0) \ - _set_->root = NULL; \ - \ - _set_->count--; \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->delete) \ - _set_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ - \ - while (scan->right != NULL) \ - scan = scan->right; \ - \ - if (value) \ - *value = scan->value; \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ - \ - while (scan->left != NULL) \ - scan = scan->left; \ - \ - if (value) \ - *value = scan->value; \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ - { \ - bool result = CMC_(PFX, _impl_get_node)(_set_, value) != NULL; \ - \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _empty)(struct SNAME * _set_) \ - { \ - return _set_->count == 0; \ - } \ - \ - size_t CMC_(PFX, _count)(struct SNAME * _set_) \ - { \ - return _set_->count; \ - } \ - \ - int CMC_(PFX, _flag)(struct SNAME * _set_) \ - { \ - return _set_->flag; \ - } \ - \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - _set_->f_val, _set_->alloc, _set_->callbacks); \ - \ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ - \ - if (!CMC_(PFX, _empty)(_set_)) \ - { \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); \ - CMC_(PFX, _iter_next)(&iter)) \ - { \ - if (_set_->f_val->cpy) \ - CMC_(PFX, _insert) \ - (result, _set_->f_val->cpy(CMC_(PFX, _iter_value)(&iter))); \ - else CMC_(PFX, _insert)(result, \ - CMC_(PFX, _iter_value)(&iter)); \ - } \ - } \ - \ - _set_->flag = CMC_FLAG_OK; \ - \ - return result; \ - } \ - \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - if (_set1_->count != _set2_->count) \ - return false; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - if (CMC_(PFX, _impl_get_node)( \ - _set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \ - { \ - struct cmc_string str; \ - struct SNAME *s_ = _set_; \ - \ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treeset, \ - #SNAME, #V, s_, s_->root, s_->count, s_->flag, \ - s_->f_val, s_->alloc, s_->callbacks); \ - \ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = _set_->root; \ - \ - bool left_done = false; \ - \ - while (root) \ - { \ - if (!left_done) \ - { \ - while (root->left) \ - root = root->left; \ - } \ - \ - if (!_set_->f_val->str(fptr, root->value)) \ - return false; \ - \ - left_done = true; \ - \ - if (root->right) \ - { \ - left_done = false; \ - root = root->right; \ - } \ - else if (root->parent) \ - { \ - while (root->parent && root == root->parent->right) \ - root = root->parent; \ - \ - if (!root->parent) \ - break; \ - \ - root = root->parent; \ - } \ - else \ - break; \ - } \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)( \ - _set1_->f_val, _set1_->alloc, _set1_->callbacks); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ - } \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)( \ - _set1_->f_val, _set1_->alloc, _set1_->callbacks); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - /** TODO Should this compare count or capacity? */ \ - struct SNAME *_set_A_ = \ - _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_node)(_set_B_, value) != NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)( \ - _set1_->f_val, _set1_->alloc, _set1_->callbacks); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)( \ - _set1_->f_val, _set1_->alloc, _set1_->callbacks); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - if (CMC_(PFX, _impl_get_node)(_set1_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - return _set_r_; \ - } \ - \ - /* Is _set1_ a subset of _set2_ ? */ \ - /* A set X is a subset of a set Y when: X <= Y */ \ - /* If X is a subset of Y, then Y is a superset of X */ \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* If the cardinality of _set1_ is greater than that of _set2_ */ \ - /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ - if (_set1_->count > _set2_->count) \ - return false; \ - \ - /* The empty set is a subset of all sets */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - /* Is _set1_ a superset of _set2_ ? */ \ - /* A set X is a superset of a set Y when: X >= Y */ \ - /* If X is a superset of Y, then Y is a subset of X */ \ + static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, struct CMC_DEF_NODE(SNAME) * node); \ +\ + struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _new_custom)(f_val, NULL, NULL); \ + } \ +\ + struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ +\ + if (!_set_) \ + return NULL; \ +\ + _set_->count = 0; \ + _set_->root = NULL; \ + _set_->flag = CMC_FLAG_OK; \ + _set_->f_val = f_val; \ + _set_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ +\ + return _set_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _set_) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ + struct CMC_DEF_NODE(SNAME) *up = NULL; \ +\ + while (scan != NULL) \ + { \ + if (scan->left != NULL) \ + { \ + struct CMC_DEF_NODE(SNAME) *left = scan->left; \ +\ + scan->left = up; \ + up = scan; \ + scan = left; \ + } \ + else if (scan->right != NULL) \ + { \ + struct CMC_DEF_NODE(SNAME) *right = scan->right; \ +\ + scan->left = up; \ + scan->right = NULL; \ + up = scan; \ + scan = right; \ + } \ + else \ + { \ + if (up == NULL) \ + { \ + if (_set_->f_val->free) \ + _set_->f_val->free(scan->value); \ +\ + _set_->alloc->free(scan); \ + scan = NULL; \ + } \ +\ + while (up != NULL) \ + { \ + if (_set_->f_val->free) \ + _set_->f_val->free(scan->value); \ +\ + _set_->alloc->free(scan); \ +\ + if (up->right != NULL) \ + { \ + scan = up->right; \ + up->right = NULL; \ + break; \ + } \ + else \ + { \ + scan = up; \ + up = up->left; \ + } \ + } \ + } \ + } \ +\ + _set_->count = 0; \ + _set_->root = NULL; \ + _set_->flag = CMC_FLAG_OK; \ + } \ +\ + void CMC_(PFX, _free)(struct SNAME * _set_) \ + { \ + CMC_(PFX, _clear)(_set_); \ +\ + _set_->alloc->free(_set_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + if (!alloc) \ + _set_->alloc = &cmc_alloc_node_default; \ + else \ + _set_->alloc = alloc; \ +\ + CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ +\ + _set_->flag = CMC_FLAG_OK; \ + } \ +\ + bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->root = CMC_(PFX, _impl_new_node)(_set_, value); \ +\ + if (!_set_->root) \ + { \ + _set_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ + } \ + else \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ + struct CMC_DEF_NODE(SNAME) *parent = scan; \ +\ + while (scan != NULL) \ + { \ + parent = scan; \ +\ + if (_set_->f_val->cmp(scan->value, value) > 0) \ + scan = scan->left; \ + else if (_set_->f_val->cmp(scan->value, value) < 0) \ + scan = scan->right; \ + else \ + { \ + _set_->flag = CMC_FLAG_DUPLICATE; \ + return false; \ + } \ + } \ +\ + struct CMC_DEF_NODE(SNAME) * node; \ +\ + if (_set_->f_val->cmp(parent->value, value) > 0) \ + { \ + parent->left = CMC_(PFX, _impl_new_node)(_set_, value); \ +\ + if (!parent->left) \ + { \ + _set_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + parent->left->parent = parent; \ + node = parent->left; \ + } \ + else \ + { \ + parent->right = CMC_(PFX, _impl_new_node)(_set_, value); \ +\ + if (!parent->right) \ + { \ + _set_->flag = CMC_FLAG_ALLOC; \ + return false; \ + } \ +\ + parent->right->parent = parent; \ + node = parent->right; \ + } \ +\ + CMC_(PFX, _impl_rebalance)(_set_, node); \ + } \ +\ + _set_->count++; \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->create) \ + _set_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_set_, value); \ +\ + if (!node) \ + { \ + _set_->flag = CMC_FLAG_NOT_FOUND; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \ +\ + bool is_root = node->parent == NULL; \ +\ + if (node->left == NULL && node->right == NULL) \ + { \ + if (is_root) \ + _set_->root = NULL; \ + else \ + { \ + unbalanced = node->parent; \ +\ + if (node->parent->right == node) \ + node->parent->right = NULL; \ + else \ + node->parent->left = NULL; \ + } \ +\ + _set_->alloc->free(node); \ + } \ + else if (node->left == NULL) \ + { \ + if (is_root) \ + { \ + _set_->root = node->right; \ + _set_->root->parent = NULL; \ + } \ + else \ + { \ + unbalanced = node->parent; \ +\ + node->right->parent = node->parent; \ +\ + if (node->parent->right == node) \ + node->parent->right = node->right; \ + else \ + node->parent->left = node->right; \ + } \ +\ + _set_->alloc->free(node); \ + } \ + else if (node->right == NULL) \ + { \ + if (is_root) \ + { \ + _set_->root = node->left; \ + _set_->root->parent = NULL; \ + } \ + else \ + { \ + unbalanced = node->parent; \ +\ + node->left->parent = node->parent; \ +\ + if (node->parent->right == node) \ + node->parent->right = node->left; \ + else \ + node->parent->left = node->left; \ + } \ +\ + _set_->alloc->free(node); \ + } \ + else \ + { \ + temp = node->right; \ + while (temp->left != NULL) \ + temp = temp->left; \ +\ + V temp_value = temp->value; \ +\ + unbalanced = temp->parent; \ +\ + if (temp->left == NULL && temp->right == NULL) \ + { \ + if (temp->parent->right == temp) \ + temp->parent->right = NULL; \ + else \ + temp->parent->left = NULL; \ + } \ + else if (temp->left == NULL) \ + { \ + temp->right->parent = temp->parent; \ +\ + if (temp->parent->right == temp) \ + temp->parent->right = temp->right; \ + else \ + temp->parent->left = temp->right; \ + } \ + else if (temp->right == NULL) \ + { \ + temp->left->parent = temp->parent; \ +\ + if (temp->parent->right == temp) \ + temp->parent->right = temp->left; \ + else \ + temp->parent->left = temp->left; \ + } \ +\ + _set_->alloc->free(temp); \ +\ + node->value = temp_value; \ + } \ +\ + if (unbalanced != NULL) \ + CMC_(PFX, _impl_rebalance)(_set_, unbalanced); \ +\ + if (_set_->count == 0) \ + _set_->root = NULL; \ +\ + _set_->count--; \ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->delete) \ + _set_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ +\ + while (scan->right != NULL) \ + scan = scan->right; \ +\ + if (value) \ + *value = scan->value; \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ + { \ + if (CMC_(PFX, _empty)(_set_)) \ + { \ + _set_->flag = CMC_FLAG_EMPTY; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ +\ + while (scan->left != NULL) \ + scan = scan->left; \ +\ + if (value) \ + *value = scan->value; \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ + { \ + bool result = CMC_(PFX, _impl_get_node)(_set_, value) != NULL; \ +\ + if (_set_->callbacks && _set_->callbacks->read) \ + _set_->callbacks->read(); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _set_) \ + { \ + return _set_->count == 0; \ + } \ +\ + size_t CMC_(PFX, _count)(struct SNAME * _set_) \ + { \ + return _set_->count; \ + } \ +\ + int CMC_(PFX, _flag)(struct SNAME * _set_) \ + { \ + return _set_->flag; \ + } \ +\ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ + { \ + struct SNAME *result = CMC_(PFX, _new_custom)(_set_->f_val, _set_->alloc, NULL); \ +\ + if (!result) \ + { \ + _set_->flag = CMC_FLAG_ERROR; \ + return NULL; \ + } \ +\ + CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \ +\ + if (!CMC_(PFX, _empty)(_set_)) \ + { \ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + if (_set_->f_val->cpy) \ + CMC_(PFX, _insert) \ + (result, _set_->f_val->cpy(CMC_(PFX, _iter_value)(&iter))); \ + else CMC_(PFX, _insert)(result, CMC_(PFX, _iter_value)(&iter)); \ + } \ + } \ +\ + _set_->flag = CMC_FLAG_OK; \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ +\ + if (_set1_->count != _set2_->count) \ + return false; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + if (CMC_(PFX, _impl_get_node)(_set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \ + { \ + struct cmc_string str; \ + struct SNAME *s_ = _set_; \ +\ + int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treeset, #SNAME, #V, s_, s_->root, s_->count, \ + s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ +\ + return n >= 0 ? str : (struct cmc_string){ 0 }; \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \ + { \ + struct CMC_DEF_NODE(SNAME) *root = _set_->root; \ +\ + bool left_done = false; \ +\ + while (root) \ + { \ + if (!left_done) \ + { \ + while (root->left) \ + root = root->left; \ + } \ +\ + if (!_set_->f_val->str(fptr, root->value)) \ + return false; \ +\ + left_done = true; \ +\ + if (root->right) \ + { \ + left_done = false; \ + root = root->right; \ + } \ + else if (root->parent) \ + { \ + while (root->parent && root == root->parent->right) \ + root = root->parent; \ +\ + if (!root->parent) \ + break; \ +\ + root = root->parent; \ + } \ + else \ + break; \ + } \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + /** TODO Should this compare count or capacity? */ \ + struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ + struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set_B_, value) != NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ +\ + if (CMC_(PFX, _impl_get_node)(_set1_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + /* Is _set1_ a subset of _set2_ ? */ \ + /* A set X is a subset of a set Y when: X <= Y */ \ + /* If X is a subset of Y, then Y is a superset of X */ \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* If the cardinality of _set1_ is greater than that of _set2_ */ \ + /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ + if (_set1_->count > _set2_->count) \ + return false; \ +\ + /* The empty set is a subset of all sets */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + /* Is _set1_ a superset of _set2_ ? */ \ + /* A set X is a superset of a set Y when: X >= Y */ \ + /* If X is a superset of Y, then Y is a subset of X */ \ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ - \ - /* Is _set1_ a proper subset of _set2_ ? */ \ - /* A set X is a proper subset of a set Y when: X < Y */ \ - /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* If the cardinality of _set1_ is greater than or equal to that */ \ - /* of _set2_, then it is safe to say that _set1_ can't be a proper */ \ - /* subset of _set2_ */ \ - if (_set1_->count >= _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - /* The empty set is a proper subset of all non-empty sets */ \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ + { \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ + } \ +\ + /* Is _set1_ a proper subset of _set2_ ? */ \ + /* A set X is a proper subset of a set Y when: X < Y */ \ + /* If X is a proper subset of Y, then Y is a proper superset of X */ \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* If the cardinality of _set1_ is greater than or equal to that */ \ + /* of _set2_, then it is safe to say that _set1_ can't be a proper */ \ + /* subset of _set2_ */ \ + if (_set1_->count >= _set2_->count) \ + return false; \ +\ + if (CMC_(PFX, _empty)(_set1_)) \ + { \ + /* The empty set is a proper subset of all non-empty sets */ \ + if (!CMC_(PFX, _empty)(_set2_)) \ + return true; \ /* The empty set is not a proper subset of itself (this is true */ \ - /* for any set) */ \ - else \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - /* Is _set1_ a proper superset of _set2_ ? */ \ - /* A set X is a proper superset of a set Y when: X > Y */ \ - /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ - \ - /* Is _set1_ a disjointset of _set2_ ? */ \ - /* A set X is a disjointset of a set Y if their intersection is empty, */ \ - /* that is, if there are no elements in common between the two */ \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* The intersection of an empty set with any other set will result */ \ - /* in an empty set */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_node)(_set2_, value) != NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->left != NULL) \ - iter.cursor = iter.cursor->left; \ - \ - iter.first = iter.cursor; \ - \ - iter.last = target->root; \ - while (iter.last->right != NULL) \ - iter.last = iter.last->right; \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->right != NULL) \ - iter.cursor = iter.cursor->right; \ - \ - iter.last = iter.cursor; \ - \ - iter.first = target->root; \ - while (iter.first->left != NULL) \ - iter.first = iter.first->left; \ - \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->first; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->cursor = iter->last; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - if (iter->cursor->right != NULL) \ - { \ - iter->cursor = iter->cursor->right; \ - \ - while (iter->cursor->left != NULL) \ - iter->cursor = iter->cursor->left; \ - \ - iter->index++; \ - \ - return true; \ - } \ - \ - while (true) \ - { \ - if (iter->cursor->parent->left == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ - \ - iter->index++; \ - \ - return true; \ - } \ - \ - iter->cursor = iter->cursor->parent; \ - } \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - if (iter->cursor->left != NULL) \ - { \ - iter->cursor = iter->cursor->left; \ - \ - while (iter->cursor->right != NULL) \ - iter->cursor = iter->cursor->right; \ - \ - iter->index--; \ - \ - return true; \ - } \ - \ - while (true) \ - { \ - if (iter->cursor->parent->right == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ - \ - iter->index--; \ - \ - return true; \ - } \ - \ - iter->cursor = iter->cursor->parent; \ - } \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->cursor->value; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ - static struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *node = \ - _set_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ - \ - if (!node) \ - return NULL; \ - \ - node->value = value; \ - node->right = NULL; \ - node->left = NULL; \ - node->parent = NULL; \ - node->height = 0; \ - \ - return node; \ - } \ - \ - static struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ - \ - while (scan != NULL) \ - { \ - if (_set_->f_val->cmp(scan->value, value) > 0) \ - scan = scan->left; \ - else if (_set_->f_val->cmp(scan->value, value) < 0) \ - scan = scan->right; \ - else \ - return scan; \ - } \ - \ - return NULL; \ - } \ - \ + /* for any set) */ \ + else \ + return false; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + /* Is _set1_ a proper superset of _set2_ ? */ \ + /* A set X is a proper superset of a set Y when: X > Y */ \ + /* If X is a proper superset of Y, then Y is a proper subset of X */ \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ + } \ +\ + /* Is _set1_ a disjointset of _set2_ ? */ \ + /* A set X is a disjointset of a set Y if their intersection is empty, */ \ + /* that is, if there are no elements in common between the two */ \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* The intersection of an empty set with any other set will result */ \ + /* in an empty set */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) != NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->left != NULL) \ + iter.cursor = iter.cursor->left; \ +\ + iter.first = iter.cursor; \ +\ + iter.last = target->root; \ + while (iter.last->right != NULL) \ + iter.last = iter.last->right; \ + } \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->right != NULL) \ + iter.cursor = iter.cursor->right; \ +\ + iter.last = iter.cursor; \ +\ + iter.first = target->root; \ + while (iter.first->left != NULL) \ + iter.first = iter.first->left; \ +\ + iter.index = target->count - 1; \ + } \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->first; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + iter->cursor = iter->last; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->right != NULL) \ + { \ + iter->cursor = iter->cursor->right; \ +\ + while (iter->cursor->left != NULL) \ + iter->cursor = iter->cursor->left; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->left == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->left != NULL) \ + { \ + iter->cursor = iter->cursor->left; \ +\ + while (iter->cursor->right != NULL) \ + iter->cursor = iter->cursor->right; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->right == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->cursor->value; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } \ +\ + static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *node = _set_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ +\ + if (!node) \ + return NULL; \ +\ + node->value = value; \ + node->right = NULL; \ + node->left = NULL; \ + node->parent = NULL; \ + node->height = 0; \ +\ + return node; \ + } \ +\ + static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ +\ + while (scan != NULL) \ + { \ + if (_set_->f_val->cmp(scan->value, value) > 0) \ + scan = scan->left; \ + else if (_set_->f_val->cmp(scan->value, value) < 0) \ + scan = scan->right; \ + else \ + return scan; \ + } \ +\ + return NULL; \ + } \ +\ static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node) \ - { \ - if (node == NULL) \ - return 0; \ - \ - return node->height; \ - } \ - \ - static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * \ - node) \ - { \ - if (node == NULL) \ - return 0; \ - \ - unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \ - unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \ - \ - return 1 + (h_l > h_r ? h_l : h_r); \ - } \ - \ + { \ + if (node == NULL) \ + return 0; \ +\ + return node->height; \ + } \ +\ + static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node) \ + { \ + if (node == NULL) \ + return 0; \ +\ + unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \ + unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \ +\ + return 1 + (h_l > h_r ? h_l : h_r); \ + } \ +\ static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = *Z; \ - struct CMC_DEF_NODE(SNAME) *new_root = root->left; \ - \ - if (root->parent != NULL) \ - { \ - if (root->parent->left == root) \ - root->parent->left = new_root; \ - else \ - root->parent->right = new_root; \ - } \ - \ - new_root->parent = root->parent; \ - \ - root->parent = new_root; \ - root->left = new_root->right; \ - \ - if (root->left) \ - root->left->parent = root; \ - \ - new_root->right = root; \ - \ - root->height = CMC_(PFX, _impl_hupdate)(root); \ - new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ - \ - *Z = new_root; \ - } \ - \ - static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = *Z; \ - struct CMC_DEF_NODE(SNAME) *new_root = root->right; \ - \ - if (root->parent != NULL) \ - { \ - if (root->parent->right == root) \ - root->parent->right = new_root; \ - else \ - root->parent->left = new_root; \ - } \ - \ - new_root->parent = root->parent; \ - \ - root->parent = new_root; \ - root->right = new_root->left; \ - \ - if (root->right) \ - root->right->parent = root; \ - \ - new_root->left = root; \ - \ - root->height = CMC_(PFX, _impl_hupdate)(root); \ - new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ - \ - *Z = new_root; \ - } \ - \ - static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, \ - struct CMC_DEF_NODE(SNAME) * node) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \ - \ - int balance; \ - bool is_root = false; \ - \ - while (scan != NULL) \ - { \ - if (scan->parent == NULL) \ - is_root = true; \ - \ - scan->height = CMC_(PFX, _impl_hupdate)(scan); \ - balance = CMC_(PFX, _impl_h)(scan->right) - \ - CMC_(PFX, _impl_h)(scan->left); \ - \ - if (balance >= 2) \ - { \ - child = scan->right; \ - \ - if (CMC_(PFX, _impl_h)(child->right) < \ - CMC_(PFX, _impl_h)(child->left)) \ - CMC_(PFX, _impl_rotate_right)(&(scan->right)); \ - \ - CMC_(PFX, _impl_rotate_left)(&scan); \ - } \ - else if (balance <= -2) \ - { \ - child = scan->left; \ - \ - if (CMC_(PFX, _impl_h)(child->left) < \ - CMC_(PFX, _impl_h)(child->right)) \ - CMC_(PFX, _impl_rotate_left)(&(scan->left)); \ - \ - CMC_(PFX, _impl_rotate_right)(&scan); \ - } \ - \ - if (is_root) \ - { \ - _set_->root = scan; \ - is_root = false; \ - } \ - \ - scan = scan->parent; \ - } \ + { \ + struct CMC_DEF_NODE(SNAME) *root = *Z; \ + struct CMC_DEF_NODE(SNAME) *new_root = root->left; \ +\ + if (root->parent != NULL) \ + { \ + if (root->parent->left == root) \ + root->parent->left = new_root; \ + else \ + root->parent->right = new_root; \ + } \ +\ + new_root->parent = root->parent; \ +\ + root->parent = new_root; \ + root->left = new_root->right; \ +\ + if (root->left) \ + root->left->parent = root; \ +\ + new_root->right = root; \ +\ + root->height = CMC_(PFX, _impl_hupdate)(root); \ + new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ +\ + *Z = new_root; \ + } \ +\ + static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \ + { \ + struct CMC_DEF_NODE(SNAME) *root = *Z; \ + struct CMC_DEF_NODE(SNAME) *new_root = root->right; \ +\ + if (root->parent != NULL) \ + { \ + if (root->parent->right == root) \ + root->parent->right = new_root; \ + else \ + root->parent->left = new_root; \ + } \ +\ + new_root->parent = root->parent; \ +\ + root->parent = new_root; \ + root->right = new_root->left; \ +\ + if (root->right) \ + root->right->parent = root; \ +\ + new_root->left = root; \ +\ + root->height = CMC_(PFX, _impl_hupdate)(root); \ + new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ +\ + *Z = new_root; \ + } \ +\ + static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, struct CMC_DEF_NODE(SNAME) * node) \ + { \ + struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \ +\ + int balance; \ + bool is_root = false; \ +\ + while (scan != NULL) \ + { \ + if (scan->parent == NULL) \ + is_root = true; \ +\ + scan->height = CMC_(PFX, _impl_hupdate)(scan); \ + balance = CMC_(PFX, _impl_h)(scan->right) - CMC_(PFX, _impl_h)(scan->left); \ +\ + if (balance >= 2) \ + { \ + child = scan->right; \ +\ + if (CMC_(PFX, _impl_h)(child->right) < CMC_(PFX, _impl_h)(child->left)) \ + CMC_(PFX, _impl_rotate_right)(&(scan->right)); \ +\ + CMC_(PFX, _impl_rotate_left)(&scan); \ + } \ + else if (balance <= -2) \ + { \ + child = scan->left; \ +\ + if (CMC_(PFX, _impl_h)(child->left) < CMC_(PFX, _impl_h)(child->right)) \ + CMC_(PFX, _impl_rotate_left)(&(scan->left)); \ +\ + CMC_(PFX, _impl_rotate_right)(&scan); \ + } \ +\ + if (is_root) \ + { \ + _set_->root = scan; \ + is_root = false; \ + } \ +\ + scan = scan->parent; \ + } \ } #endif /* CMC_CMC_TREESET_H */ diff --git a/src/cor/alloc.h b/src/cor/alloc.h index 616d7d2..5d3edea 100644 --- a/src/cor/alloc.h +++ b/src/cor/alloc.h @@ -11,6 +11,12 @@ #ifndef CMC_COR_ALLOC_H #define CMC_COR_ALLOC_H +#ifdef CMC_CAMEL_CASE +#define CMC_ALLOC_NODE_NAME CMCAllocNode +#else +#define CMC_ALLOC_NODE_NAME cmc_alloc_node +#endif + #include /** @@ -20,7 +26,7 @@ * functions. The cmc_alloc_node_default is the default heap allocator provided * by the standard library. */ -static struct cmc_alloc_node +static struct CMC_ALLOC_NODE_NAME { void *(*malloc)(size_t); void *(*calloc)(size_t, size_t); diff --git a/src/cor/callbacks.h b/src/cor/callbacks.h index 5083cad..970634f 100644 --- a/src/cor/callbacks.h +++ b/src/cor/callbacks.h @@ -8,8 +8,32 @@ * */ -#ifndef CMC_COR_CALLBACK_H -#define CMC_COR_CALLBACK_H +#ifndef CMC_COR_CALLBACKS_H +#define CMC_COR_CALLBACKS_H + +#ifdef CMC_CAMEL_CASE +#define CMC_CALLBACKS_NAME CMCCallbacks +#else +#define CMC_CALLBACKS_NAME cmc_callbacks +#endif + +#ifdef CMC_NO_CALLBACKS + +#define CMC_CALLBACKS_DECL +#define CMC_CALLBACKS_GET(ds) NULL /* Placeholder for STR */ +#define CMC_CALLBACKS_ASSIGN(ds, cb) +#define CMC_CALLBACKS_CALL(ds, cb) + +#else + +#define CMC_CALLBACKS_DECL struct CMC_CALLBACKS_NAME *callbacks +#define CMC_CALLBACKS_GET(ds) (ds)->callbacks +#define CMC_CALLBACKS_ASSIGN(ds, cb) CMC_CALLBACKS_GET(ds) = cb +#define CMC_CALLBACKS_CALL(ds, cb) \ + if (CMC_CALLBACKS_GET(ds) && CMC_CALLBACKS_GET(ds)->cb) \ + CMC_CALLBACKS_GET(ds)->cb(); + +#endif /** * struct cmc_callbacks @@ -21,7 +45,7 @@ * - delete : an element was successfully removed from the collection * - resize : the collection was full and successfully resized */ -struct cmc_callbacks +struct CMC_CALLBACKS_NAME { void (*create)(void); void (*read)(void); @@ -30,4 +54,4 @@ struct cmc_callbacks void (*resize)(void); }; -#endif /* CMC_COR_CALLBACK_H */ +#endif /* CMC_COR_CALLBACKS_H */ diff --git a/src/cor/flags.h b/src/cor/flags.h index 6c0827c..e080a53 100644 --- a/src/cor/flags.h +++ b/src/cor/flags.h @@ -37,9 +37,7 @@ enum cmc_flags * * Maps the error codes to their character representation. */ -const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY", - "NOT_FOUND", "INVALID", "RANGE", - "DUPLICATE", "ERROR", "THREAD", - "MUTEX" }; +const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID", + "RANGE", "DUPLICATE", "ERROR", "THREAD", "MUTEX" }; #endif /* CMC_COR_FLAGS_H */ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index b3e5e71..8dc1898 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -24,422 +24,401 @@ * The part 'INIT' gives a new way of initializing a collection. The collection * struct is not heap allocated, only its internal structure (nodes, buffers). */ -#define CMC_EXT_CMC_DEQUE_INIT(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_INIT(PARAMS) \ CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS) #define CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \ - CMC_EXT_CMC_DEQUE_INIT_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_DEQUE_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS) \ - CMC_EXT_CMC_DEQUE_INIT_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_DEQUE_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ - \ - struct SNAME CMC_(PFX, _init)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME CMC_(PFX, _init_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ +#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ +\ + struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ void CMC_(PFX, _release)(struct SNAME _deque_); -#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ - \ - struct SNAME CMC_(PFX, _init)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \ - } \ - \ - struct SNAME CMC_(PFX, _init_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - struct SNAME _deque_ = { 0 }; \ - \ - if (capacity < 1) \ - return _deque_; \ - \ - if (!f_val) \ - return _deque_; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_deque_.buffer) \ - return _deque_; \ - \ - _deque_.capacity = capacity; \ - _deque_.count = 0; \ - _deque_.front = 0; \ - _deque_.back = 0; \ - _deque_.flag = CMC_FLAG_OK; \ - _deque_.f_val = f_val; \ - _deque_.alloc = alloc; \ - _deque_.callbacks = callbacks; \ - \ - return _deque_; \ - } \ - \ - void CMC_(PFX, _release)(struct SNAME _deque_) \ - { \ - if (_deque_.f_val->free) \ - { \ +#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ +\ + struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \ + } \ +\ + struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + struct SNAME _deque_ = { 0 }; \ +\ + if (capacity < 1) \ + return _deque_; \ +\ + if (!f_val) \ + return _deque_; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ +\ + if (!_deque_.buffer) \ + return _deque_; \ +\ + _deque_.capacity = capacity; \ + _deque_.count = 0; \ + _deque_.front = 0; \ + _deque_.back = 0; \ + _deque_.flag = CMC_FLAG_OK; \ + _deque_.f_val = f_val; \ + _deque_.alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(&_deque_, callbacks); \ +\ + return _deque_; \ + } \ +\ + void CMC_(PFX, _release)(struct SNAME _deque_) \ + { \ + if (_deque_.f_val->free) \ + { \ for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ - { \ - _deque_.f_val->free(_deque_.buffer[i]); \ - \ - i = (i + 1) % _deque_.capacity; \ - } \ - } \ - \ - _deque_.alloc->free(_deque_.buffer); \ + { \ + _deque_.f_val->free(_deque_.buffer[i]); \ +\ + i = (i + 1) % _deque_.capacity; \ + } \ + } \ +\ + _deque_.alloc->free(_deque_.buffer); \ } /** * ITER */ -#define CMC_EXT_CMC_DEQUE_ITER(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_ITER(PARAMS) \ CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS) #define CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_DEQUE_ITER_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_DEQUE_ITER_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \ - \ - /* Deque Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target deque */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* Deque Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target deque */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_DEQUE_ITER_SOURCE_(PFX, SNAME, V) \ - \ +#define CMC_EXT_CMC_DEQUE_ITER_SOURCE_(PFX, SNAME, V) \ +\ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->front; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - if (iter.target->back == 0) \ - iter.cursor = iter.target->capacity - 1; \ - else \ - iter.cursor = iter.target->back - 1; \ - \ - iter.index = iter.target->count - 1; \ - } \ - else \ - { \ - iter.cursor = 0; \ - iter.index = 0; \ - } \ - \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - if (iter->target->back == 0) \ - iter->cursor = iter->target->capacity - 1; \ - else \ - iter->cursor = iter->target->back - 1; \ - \ - iter->index = iter->target->count - 1; \ - \ - iter->start = false; \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \ - : iter->cursor - 1; \ - iter->index--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index += steps; \ - iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index -= steps; \ - \ - /* Prevent underflow */ \ - if (iter->cursor < steps) \ - iter->cursor += iter->target->capacity; \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->front; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + if (iter.target->back == 0) \ + iter.cursor = iter.target->capacity - 1; \ + else \ + iter.cursor = iter.target->back - 1; \ +\ + iter.index = iter.target->count - 1; \ + } \ + else \ + { \ + iter.cursor = 0; \ + iter.index = 0; \ + } \ +\ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->front; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = false; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + if (iter->target->back == 0) \ + iter->cursor = iter->target->capacity - 1; \ + else \ + iter->cursor = iter->target->back - 1; \ +\ + iter->index = iter->target->count - 1; \ +\ + iter->start = false; \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ + iter->index++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \ + iter->index--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->index += steps; \ + iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->index -= steps; \ +\ + /* Prevent underflow */ \ + if (iter->cursor < steps) \ + iter->cursor += iter->target->capacity; \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->target->buffer[iter->cursor]); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ } /** * STR */ -#define CMC_EXT_CMC_DEQUE_STR(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_STR(PARAMS) \ CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS) #define CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_DEQUE_STR_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_DEQUE_STR_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \ - \ +#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \ +\ bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \ - const char *start, const char *separator, \ + bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, const char *start, const char *separator, \ const char *end); -#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \ - { \ - struct SNAME *d_ = _deque_; \ - \ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "front:%" PRIuMAX ", " \ - "back:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, \ - d_->buffer, d_->capacity, d_->count, d_->front, \ - d_->back, d_->flag, d_->f_val, d_->alloc, \ - d_->callbacks); \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, \ - const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ - \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \ - return false; \ - \ - i = (i + 1) % _deque_->capacity; \ - \ - if (j + 1 < _deque_->count) \ - fprintf(fptr, "%s", separator); \ - } \ - \ - fprintf(fptr, "%s", end); \ - \ - return true; \ +#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \ + { \ + struct SNAME *d_ = _deque_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "front:%" PRIuMAX ", " \ + "back:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, d_->buffer, d_->capacity, d_->count, \ + d_->front, d_->back, d_->flag, d_->f_val, d_->alloc, CMC_CALLBACKS_GET(d_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ + { \ + if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \ + return false; \ +\ + i = (i + 1) % _deque_->capacity; \ +\ + if (j + 1 < _deque_->count) \ + fprintf(fptr, "%s", separator); \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ } #endif /* CMC_EXT_CMC_DEQUE_H */ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 44fea59..b2adb37 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -24,524 +24,499 @@ * The part 'INIT' gives a new way of initializing a collection. The collection * struct is not heap allocated, only its internal structure (nodes, buffers). */ -#define CMC_EXT_CMC_HASHMAP_INIT(PARAMS) \ +#define CMC_EXT_CMC_HASHMAP_INIT(PARAMS) \ CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#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, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - 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); \ +#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, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + 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_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * callbacks); \ void CMC_(PFX, _release)(struct SNAME _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_; \ - } \ - \ - void CMC_(PFX, _release)(struct SNAME _map_) \ - { \ - if (_map_.f_key->free || _map_.f_val->free) \ - { \ - 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->free) \ - _map_.f_key->free(entry->key); \ - if (_map_.f_val->free) \ - _map_.f_val->free(entry->value); \ - } \ - } \ - } \ - \ - _map_.alloc->free(_map_.buffer); \ +#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_NAME * alloc, \ + struct CMC_CALLBACKS_NAME * 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; \ + CMC_CALLBACKS_ASSIGN(&_map_, callbacks); \ +\ + return _map_; \ + } \ +\ + void CMC_(PFX, _release)(struct SNAME _map_) \ + { \ + if (_map_.f_key->free || _map_.f_val->free) \ + { \ + 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->free) \ + _map_.f_key->free(entry->key); \ + if (_map_.f_val->free) \ + _map_.f_val->free(entry->value); \ + } \ + } \ + } \ +\ + _map_.alloc->free(_map_.buffer); \ } /** * ITER */ -#define CMC_EXT_CMC_HASHMAP_ITER(PARAMS) \ +#define CMC_EXT_CMC_HASHMAP_ITER(PARAMS) \ CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \ - \ - /* HashMap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target hashmap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \ +\ + /* HashMap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target hashmap */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* The index of the first element */ \ + size_t first; \ +\ + /* The index of the last element */ \ + size_t last; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ - \ +#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ +\ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index++; \ - \ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index--; \ - \ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ +\ + iter.cursor = iter.first; \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ +\ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ +\ + iter->index++; \ +\ + while (1) \ + { \ + iter->cursor++; \ + scan = &(iter->target->buffer[iter->cursor]); \ +\ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ +\ + iter->index--; \ +\ + while (1) \ + { \ + iter->cursor--; \ + scan = &(iter->target->buffer[iter->cursor]); \ +\ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].key; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].value; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor].value); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (K){ 0 }; \ +\ + return iter->target->buffer[iter->cursor].key; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor].value; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->target->buffer[iter->cursor].value); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ } /** * STR */ -#define CMC_EXT_CMC_HASHMAP_STR(PARAMS) \ +#define CMC_EXT_CMC_HASHMAP_STR(PARAMS) \ CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), \ - CMC_PARAM_K(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, K, V) \ - \ - 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, \ +#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, K, V) \ +\ + 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 *key_val_sep); -#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, \ - "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 }", \ - 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; \ +#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, \ + "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 }", \ + 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, CMC_CALLBACKS_GET(m_)); \ + } \ +\ + 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/ext/cmc/hashmultimap.h b/src/ext/cmc/hashmultimap.h index 3730f45..ac03bd6 100644 --- a/src/ext/cmc/hashmultimap.h +++ b/src/ext/cmc/hashmultimap.h @@ -21,451 +21,437 @@ /** * ITER */ -#define CMC_EXT_CMC_HASHMULTIMAP_ITER(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTIMAP_ITER(PARAMS) \ CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \ - \ - /* HashMultiMap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target hashmultimap */ \ - struct SNAME *target; \ - \ - /* Current entry */ \ - struct CMC_DEF_ENTRY(SNAME) * curr_entry; \ - \ - /* Cursor`s position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \ +\ + /* HashMultiMap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target hashmultimap */ \ + struct SNAME *target; \ +\ + /* Current entry */ \ + struct CMC_DEF_ENTRY(SNAME) * curr_entry; \ +\ + /* Cursor`s position (index) */ \ + size_t cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* The index of the first element */ \ + size_t first; \ +\ + /* The index of the last element */ \ + size_t last; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.curr_entry = NULL; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ - \ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter.curr_entry = target->buffer[i][0]; \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.curr_entry = NULL; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter.curr_entry = target->buffer[i][0]; \ + iter.first = i; \ + break; \ + } \ + } \ +\ + iter.cursor = iter.first; \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \ - \ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.curr_entry = NULL; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ - \ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.curr_entry = NULL; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \ - \ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter.curr_entry = target->buffer[i - 1][1]; \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->curr_entry = iter->target->buffer[iter->first][0]; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->curr_entry = iter->target->buffer[iter->last][1]; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->curr_entry->next != NULL) \ - { \ - iter->curr_entry = iter->curr_entry->next; \ - iter->index++; \ - } \ - else \ - { \ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->cursor++; \ - \ - while (iter->target->buffer[iter->cursor][0] == NULL) \ - iter->cursor++; \ - \ - iter->curr_entry = iter->target->buffer[iter->cursor][0]; \ - \ - iter->index++; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->curr_entry->prev != NULL) \ - { \ - iter->curr_entry = iter->curr_entry->prev; \ - iter->index--; \ - } \ - else \ - { \ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->cursor--; \ - \ - while (iter->target->buffer[iter->cursor][1] == NULL) \ - iter->cursor--; \ - \ - iter->curr_entry = iter->target->buffer[iter->cursor][1]; \ - \ - iter->index--; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ - \ - return iter->curr_entry->key; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->curr_entry->value; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->curr_entry->value); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + iter.curr_entry = target->buffer[i - 1][1]; \ + iter.last = i - 1; \ + break; \ + } \ + } \ +\ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + iter->curr_entry = iter->target->buffer[iter->first][0]; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + iter->curr_entry = iter->target->buffer[iter->last][1]; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->curr_entry->next != NULL) \ + { \ + iter->curr_entry = iter->curr_entry->next; \ + iter->index++; \ + } \ + else \ + { \ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->cursor++; \ +\ + while (iter->target->buffer[iter->cursor][0] == NULL) \ + iter->cursor++; \ +\ + iter->curr_entry = iter->target->buffer[iter->cursor][0]; \ +\ + iter->index++; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->curr_entry->prev != NULL) \ + { \ + iter->curr_entry = iter->curr_entry->prev; \ + iter->index--; \ + } \ + else \ + { \ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->cursor--; \ +\ + while (iter->target->buffer[iter->cursor][1] == NULL) \ + iter->cursor--; \ +\ + iter->curr_entry = iter->target->buffer[iter->cursor][1]; \ +\ + iter->index--; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (K){ 0 }; \ +\ + return iter->curr_entry->key; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->curr_entry->value; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->curr_entry->value); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ } /** * STR */ -#define CMC_EXT_CMC_HASHMULTIMAP_STR(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTIMAP_STR(PARAMS) \ CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(PFX, SNAME, K, V) \ - \ - 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, \ +#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(PFX, SNAME, K, V) \ +\ + 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 *key_val_sep); -#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(PFX, SNAME, K, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ - { \ - struct SNAME *m_ = _map_; \ - \ - return 0 <= fprintf(fptr, \ - "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 }", \ - 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--) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][1]; \ - \ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ - \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ - \ - while (scan != NULL) \ - { \ - if (!_map_->f_key->str(fptr, scan->key)) \ - return false; \ - \ - fprintf(fptr, "%s", key_val_sep); \ - \ - if (!_map_->f_val->str(fptr, scan->value)) \ - return false; \ - \ - scan = scan->next; \ - \ - if (i + 1 < last) \ - fprintf(fptr, "%s", separator); \ - } \ - } \ - \ - fprintf(fptr, "%s", end); \ - \ - return true; \ +#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(PFX, SNAME, K, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ + { \ + struct SNAME *m_ = _map_; \ +\ + return 0 <= fprintf(fptr, \ + "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 }", \ + 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, CMC_CALLBACKS_GET(m_)); \ + } \ +\ + 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--) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][1]; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ +\ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ +\ + while (scan != NULL) \ + { \ + if (!_map_->f_key->str(fptr, scan->key)) \ + return false; \ +\ + fprintf(fptr, "%s", key_val_sep); \ +\ + if (!_map_->f_val->str(fptr, scan->value)) \ + return false; \ +\ + scan = scan->next; \ +\ + if (i + 1 < last) \ + fprintf(fptr, "%s", separator); \ + } \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ } #endif /* CMC_EXT_CMC_HASHMULTIMAP_H */ diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h index af1b848..2aba7c8 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext/cmc/hashmultiset.h @@ -21,727 +21,678 @@ /** * ITER */ -#define CMC_EXT_CMC_HASHMULTISET_ITER(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_ITER(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(PARAMS) #define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(PFX, SNAME, V) \ - \ - /* HashMultiSet Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target HashMultiset */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* HashMultiSet Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target HashMultiset */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* The index of the first element */ \ + size_t first; \ +\ + /* The index of the last element */ \ + size_t last; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(PFX, SNAME, V) \ - \ +#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(PFX, SNAME, V) \ +\ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index++; \ - \ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index--; \ - \ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ +\ + iter.cursor = iter.first; \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ +\ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ +\ + iter->index++; \ +\ + while (1) \ + { \ + iter->cursor++; \ + scan = &(iter->target->buffer[iter->cursor]); \ +\ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ +\ + iter->index--; \ +\ + while (1) \ + { \ + iter->cursor--; \ + scan = &(iter->target->buffer[iter->cursor]); \ +\ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].value; \ - } \ - \ - size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return 0; \ - \ - return iter->target->buffer[iter->cursor].multiplicity; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor].value; \ + } \ +\ + size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return 0; \ +\ + return iter->target->buffer[iter->cursor].multiplicity; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ } /** * SETF */ -#define CMC_EXT_CMC_HASHMULTISET_SETF(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_SETF(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) #define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(PFX, SNAME, V) \ - \ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ +#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(PFX, SNAME, V) \ +\ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_); -#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(PFX, SNAME, V) \ - \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - size_t max_ = m1 > m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ - size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ - size_t max_ = m1 > m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct SNAME *_set_A_ = \ - _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \ - size_t max_ = m1 < m2 ? m1 : m2; \ - \ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert_many) \ - (_set_r_, CMC_(PFX, _iter_value)(&iter1), \ - CMC_(PFX, _iter_multiplicity)(&iter1)); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert_many) \ - (_set_r_, CMC_(PFX, _iter_value)(&iter2), \ - CMC_(PFX, _iter_multiplicity)(&iter2)); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - return NULL; \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 != m2) \ - { \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - else \ - CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ - } \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ - size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ - \ - if (m1 != m2) \ - { \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - else \ - CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ - } \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - if (_set1_->count > _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 > m2) \ - return false; \ - } \ - \ - return true; \ - } \ - \ +#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(PFX, SNAME, V) \ +\ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ +\ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ + size_t max_ = m1 > m2 ? m1 : m2; \ +\ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ +\ + size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ + size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ + size_t max_ = m1 > m2 ? m1 : m2; \ +\ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ + struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \ + size_t max_ = m1 < m2 ? m1 : m2; \ +\ + CMC_(PFX, _update)(_set_r_, value, max_); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ +\ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + CMC_(PFX, _insert_many) \ + (_set_r_, CMC_(PFX, _iter_value)(&iter1), CMC_(PFX, _iter_multiplicity)(&iter1)); \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + CMC_(PFX, _insert_many) \ + (_set_r_, CMC_(PFX, _iter_value)(&iter2), CMC_(PFX, _iter_multiplicity)(&iter2)); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ +\ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ +\ + if (m1 != m2) \ + { \ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + else \ + CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ + } \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ +\ + size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ + size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ +\ + if (m1 != m2) \ + { \ + if (m1 > m2) \ + CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ + else \ + CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ + } \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + if (_set1_->count > _set2_->count) \ + return false; \ +\ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ +\ + if (m1 > m2) \ + return false; \ + } \ +\ + return true; \ + } \ +\ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ - \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - if (_set1_->count >= _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - else \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - \ - if (m1 >= m2) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ - \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ - return false; \ - } \ - \ - return true; \ + { \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ + } \ +\ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + if (_set1_->count >= _set2_->count) \ + return false; \ +\ + if (CMC_(PFX, _empty)(_set1_)) \ + { \ + if (!CMC_(PFX, _empty)(_set2_)) \ + return true; \ + else \ + return false; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ + size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ +\ + if (m1 >= m2) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ + } \ +\ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ + return false; \ + } \ +\ + return true; \ } /** * STR */ -#define CMC_EXT_CMC_HASHMULTISET_STR(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_STR(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(PARAMS) #define CMC_EXT_CMC_HASHMULTISET_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_STR_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \ - const char *start, const char *separator, \ +#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ const char *end, const char *key_val_sep); -#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ - { \ - struct SNAME *s_ = _set_; \ - \ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "cardinality:%" PRIuMAX ", " \ - "load:%lf, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, \ - s_->buffer, s_->capacity, s_->count, \ - s_->cardinality, s_->load, s_->flag, s_->f_val, \ - s_->alloc, s_->callbacks); \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \ - const char *start, const char *separator, \ - const char *end, const char *val_mul_sep) \ - { \ - fprintf(fptr, "%s", start); \ - \ - size_t last = 0; \ - for (size_t i = _set_->capacity; i > 0; i--) \ - { \ - if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ - \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_set_->f_val->str(fptr, entry->value)) \ - return false; \ - \ - fprintf(fptr, "%s", val_mul_sep); \ - \ +#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ + { \ + struct SNAME *s_ = _set_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "cardinality:%" PRIuMAX ", " \ + "load:%lf, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, \ + s_->cardinality, s_->load, s_->flag, s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ + const char *end, const char *val_mul_sep) \ + { \ + fprintf(fptr, "%s", start); \ +\ + size_t last = 0; \ + for (size_t i = _set_->capacity; i > 0; i--) \ + { \ + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ +\ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ +\ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (!_set_->f_val->str(fptr, entry->value)) \ + return false; \ +\ + fprintf(fptr, "%s", val_mul_sep); \ +\ if (fprintf(fptr, "%" PRIuMAX "", entry->multiplicity) < 0) \ - return false; \ - \ - if (i + 1 < last) \ - fprintf(fptr, "%s", separator); \ - } \ - } \ - \ - fprintf(fptr, "%s", end); \ - \ - return true; \ + return false; \ +\ + if (i + 1 < last) \ + fprintf(fptr, "%s", separator); \ + } \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ } #endif /* CMC_EXT_CMC_HASHMULTISET_H */ diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h index cdb627e..ac42cba 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext/cmc/hashset.h @@ -21,687 +21,646 @@ /** * ITER */ -#define CMC_EXT_CMC_HASHSET_ITER(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_ITER(PARAMS) \ CMC_EXT_CMC_HASHSET_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_HASHSET_ITER_SOURCE(PARAMS) #define CMC_EXT_CMC_HASHSET_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_ITER_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHSET_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_ITER_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHSET_ITER_HEADER_(PFX, SNAME, V) \ - \ - /* HashSet Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target HashSet */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* The index of the first element */ \ - size_t first; \ - \ - /* The index of the last element */ \ - size_t last; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_HASHSET_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* HashSet Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target HashSet */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* The index of the first element */ \ + size_t first; \ +\ + /* The index of the last element */ \ + size_t last; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_HASHSET_ITER_SOURCE_(PFX, SNAME, V) \ - \ +#define CMC_EXT_CMC_HASHSET_ITER_SOURCE_(PFX, SNAME, V) \ +\ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.first; \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ - \ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - \ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index++; \ - \ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - struct CMC_DEF_ENTRY(SNAME) *scan = \ - &(iter->target->buffer[iter->cursor]); \ - \ - iter->index--; \ - \ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ - \ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ - \ - return true; \ - } \ - \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ +\ + iter.cursor = iter.first; \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ + } \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.index = 0; \ + iter.first = 0; \ + iter.last = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + for (size_t i = 0; i < target->capacity; i++) \ + { \ + if (target->buffer[i].state == CMC_ES_FILLED) \ + { \ + iter.first = i; \ + break; \ + } \ + } \ +\ + for (size_t i = target->capacity; i > 0; i--) \ + { \ + if (target->buffer[i - 1].state == CMC_ES_FILLED) \ + { \ + iter.last = i - 1; \ + break; \ + } \ + } \ +\ + iter.cursor = iter.last; \ + iter.index = target->count - 1; \ + } \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->first; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->last; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ +\ + iter->index++; \ +\ + while (1) \ + { \ + iter->cursor++; \ + scan = &(iter->target->buffer[iter->cursor]); \ +\ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ +\ + iter->index--; \ +\ + while (1) \ + { \ + iter->cursor--; \ + scan = &(iter->target->buffer[iter->cursor]); \ +\ + if (scan->state == CMC_ES_FILLED) \ + break; \ + } \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor].value; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor].value; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ } /** * SETF */ -#define CMC_EXT_CMC_HASHSET_SETF(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_SETF(PARAMS) \ CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \ CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) #define CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_SETF_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHSET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_SETF_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHSET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHSET_SETF_HEADER_(PFX, SNAME, V) \ - \ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ +#define CMC_EXT_CMC_HASHSET_SETF_HEADER_(PFX, SNAME, V) \ +\ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_); + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_); -#define CMC_EXT_CMC_HASHSET_SETF_SOURCE_(PFX, SNAME, V) \ - \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - /* TODO turn this into a normal loop and check for errors */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct SNAME *_set_A_ = \ - _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, \ - _set1_->f_val, _set1_->alloc, NULL); \ - \ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); \ - CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter2); \ - CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ - \ - _set_r_->callbacks = _set1_->callbacks; \ - \ - return _set_r_; \ - } \ - \ - /* Is _set1_ a subset of _set2_ ? */ \ - /* A set X is a subset of a set Y when: X <= Y */ \ - /* If X is a subset of Y, then Y is a superset of X */ \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - /* If the cardinality of _set1_ is greater than that of _set2_, */ \ - /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ - if (_set1_->count > _set2_->count) \ - return false; \ - \ - /* The empty set is a subset of all sets */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - /* Is _set1_ a superset of _set2_ ? */ \ - /* A set X is a superset of a set Y when: X >= Y */ \ - /* If X is a superset of Y, then Y is a subset of X */ \ +#define CMC_EXT_CMC_HASHSET_SETF_SOURCE_(PFX, SNAME, V) \ +\ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + /* TODO turn this into a normal loop and check for errors */ \ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ + struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* Callbacks are added later */ \ + struct SNAME *_set_r_ = \ + CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + { \ + _set1_->flag = CMC_FLAG_ALLOC; \ + _set2_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ +\ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ +\ + if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + /* Is _set1_ a subset of _set2_ ? */ \ + /* A set X is a subset of a set Y when: X <= Y */ \ + /* If X is a subset of Y, then Y is a superset of X */ \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ +\ + /* If the cardinality of _set1_ is greater than that of _set2_, */ \ + /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ + if (_set1_->count > _set2_->count) \ + return false; \ +\ + /* The empty set is a subset of all sets */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + /* Is _set1_ a superset of _set2_ ? */ \ + /* A set X is a superset of a set Y when: X >= Y */ \ + /* If X is a superset of Y, then Y is a subset of X */ \ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ - \ - /* Is _set1_ a proper subset of _set2_ ? */ \ - /* A set X is a proper subset of a set Y when: X < Y */ \ - /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ + { \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ + } \ +\ + /* Is _set1_ a proper subset of _set2_ ? */ \ + /* A set X is a proper subset of a set Y when: X < Y */ \ + /* If X is a proper subset of Y, then Y is a proper superset of X */ \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ +\ /* If the cardinality of _set1_ is greater than or equal to that of */ \ - /* _set2_, then it is safe to say that _set1_ can't be a proper */ \ - /* subset of _set2_ */ \ - if (_set1_->count >= _set2_->count) \ - return false; \ - \ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - /* The empty set is a proper subset of all non-empty sets */ \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ + /* _set2_, then it is safe to say that _set1_ can't be a proper */ \ + /* subset of _set2_ */ \ + if (_set1_->count >= _set2_->count) \ + return false; \ +\ + if (CMC_(PFX, _empty)(_set1_)) \ + { \ + /* The empty set is a proper subset of all non-empty sets */ \ + if (!CMC_(PFX, _empty)(_set2_)) \ + return true; \ /* The empty set is not a proper subset of itself (this is true */ \ - /* for any set) */ \ - else \ - return false; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - return false; \ - } \ - \ - return true; \ - } \ - \ - /* Is _set1_ a proper superset of _set2_ ? */ \ - /* A set X is a proper superset of a set Y when: X > Y */ \ - /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ - \ - /* Is _set1_ a disjointset of _set2_ ? */ \ - /* A set X is a disjointset of a set Y if their intersection is empty, */ \ - /* that is, if there are no elements in common between the two */ \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, \ - struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ - \ - /* The intersection of an empty set with any other set will result */ \ - /* in an empty set */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ - \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ - \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ - \ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ - return false; \ - } \ - \ - return true; \ + /* for any set) */ \ + else \ + return false; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + /* Is _set1_ a proper superset of _set2_ ? */ \ + /* A set X is a proper superset of a set Y when: X > Y */ \ + /* If X is a proper superset of Y, then Y is a proper subset of X */ \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ + } \ +\ + /* Is _set1_ a disjointset of _set2_ ? */ \ + /* A set X is a disjointset of a set Y if their intersection is empty, */ \ + /* that is, if there are no elements in common between the two */ \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + _set1_->flag = CMC_FLAG_OK; \ + _set2_->flag = CMC_FLAG_OK; \ +\ + /* The intersection of an empty set with any other set will result */ \ + /* in an empty set */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ + return false; \ + } \ +\ + return true; \ } /** * STR */ -#define CMC_EXT_CMC_HASHSET_STR(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_STR(PARAMS) \ CMC_EXT_CMC_HASHSET_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HASHSET_STR_SOURCE(PARAMS) #define CMC_EXT_CMC_HASHSET_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_STR_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHSET_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_STR_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHSET_STR_HEADER_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \ - const char *start, const char *separator, \ +#define CMC_EXT_CMC_HASHSET_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ const char *end); -#define CMC_EXT_CMC_HASHSET_STR_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ - { \ - struct SNAME *s_ = _set_; \ - \ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "load:%lf, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks: %p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, \ - s_->buffer, s_->capacity, s_->count, s_->load, \ - s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, \ - const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ - \ - size_t last = 0; \ - for (size_t i = _set_->capacity; i > 0; i--) \ - { \ - if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ - \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_set_->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_HASHSET_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ + { \ + struct SNAME *s_ = _set_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "load:%lf, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks: %p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, s_->load, \ + s_->flag, s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + size_t last = 0; \ + for (size_t i = _set_->capacity; i > 0; i--) \ + { \ + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ +\ + for (size_t i = 0; i < _set_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ +\ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (!_set_->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_HASHSET_H */ diff --git a/src/ext/cmc/heap.h b/src/ext/cmc/heap.h index 33d8cc1..fa62ad0 100644 --- a/src/ext/cmc/heap.h +++ b/src/ext/cmc/heap.h @@ -18,301 +18,288 @@ */ #define CMC_EXT_CMC_HEAP_PARTS ITER, STR -#define CMC_EXT_CMC_HEAP_ITER(PARAMS) \ +#define CMC_EXT_CMC_HEAP_ITER(PARAMS) \ CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS) #define CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_HEAP_ITER_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_HEAP_ITER_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \ - \ - /* Heap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target heap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* Heap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target heap */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_HEAP_ITER_SOURCE_(PFX, SNAME, V) \ - \ +#define CMC_EXT_CMC_HEAP_ITER_SOURCE_(PFX, SNAME, V) \ +\ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - if (iter->end) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ +\ + if (iter->end) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor += steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ } /** * STR */ -#define CMC_EXT_CMC_HEAP_STR(PARAMS) \ +#define CMC_EXT_CMC_HEAP_STR(PARAMS) \ CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \ CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HEAP_STR_HEADER_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ - const char *start, const char *separator, \ +#define CMC_EXT_CMC_HEAP_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \ const char *end); -#define CMC_EXT_CMC_HEAP_STR_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ - { \ - struct SNAME *h_ = _heap_; \ - const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \ - \ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "type:%s, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks: %p}", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, \ - h_->buffer, h_->capacity, h_->count, t, h_->flag, \ - h_->f_val, h_->alloc, h_->callbacks); \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ - const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ - \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \ - return false; \ - \ - if (i + 1 < _heap_->count) \ - fprintf(fptr, "%s", separator); \ - } \ - \ - fprintf(fptr, "%s", end); \ - \ - return true; \ +#define CMC_EXT_CMC_HEAP_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ + { \ + struct SNAME *h_ = _heap_; \ + const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "type:%s, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks: %p}", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, h_->buffer, h_->capacity, h_->count, t, \ + h_->flag, h_->f_val, h_->alloc, CMC_CALLBACKS_GET(h_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \ + return false; \ +\ + if (i + 1 < _heap_->count) \ + fprintf(fptr, "%s", separator); \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ } #endif /* CMC_EXT_CMC_HEAP_H */ diff --git a/src/ext/cmc/intervalheap.h b/src/ext/cmc/intervalheap.h index a5d5992..d1f8ccf 100644 --- a/src/ext/cmc/intervalheap.h +++ b/src/ext/cmc/intervalheap.h @@ -21,300 +21,287 @@ /** * ITER */ -#define CMC_EXT_CMC_INTERVALHEAP_ITER(PARAMS) \ +#define CMC_EXT_CMC_INTERVALHEAP_ITER(PARAMS) \ CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) #define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \ - \ - /* IntervalHeap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target IntervalHeap */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* IntervalHeap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target IntervalHeap */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(PFX, SNAME, V) \ - \ +#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(PFX, SNAME, V) \ +\ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - if (iter->end) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ +\ + if (iter->end) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor += steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ } /** * STR */ -#define CMC_EXT_CMC_INTERVALHEAP_STR(PARAMS) \ +#define CMC_EXT_CMC_INTERVALHEAP_STR(PARAMS) \ CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \ CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) #define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ - const char *start, const char *separator, \ +#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \ const char *end); -#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ - { \ - struct SNAME *h_ = _heap_; \ - \ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "size:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, \ - h_->buffer, h_->capacity, h_->size, h_->count, \ - h_->flag, h_->f_val, h_->alloc, h_->callbacks); \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, \ - const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ - \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \ - return false; \ - \ - if (i + 1 < _heap_->count) \ - fprintf(fptr, "%s", separator); \ - } \ - \ - fprintf(fptr, "%s", end); \ - \ - return true; \ +#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ + { \ + struct SNAME *h_ = _heap_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "size:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, h_->buffer, h_->capacity, h_->size, h_->count, \ + h_->flag, h_->f_val, h_->alloc, CMC_CALLBACKS_GET(h_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + for (size_t i = 0; i < _heap_->count; i++) \ + { \ + if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \ + return false; \ +\ + if (i + 1 < _heap_->count) \ + fprintf(fptr, "%s", separator); \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ } #endif /* CMC_EXT_CMC_INTERVALHEAP_H */ diff --git a/src/ext/cmc/linkedlist.h b/src/ext/cmc/linkedlist.h index bb1f18e..0e8982c 100644 --- a/src/ext/cmc/linkedlist.h +++ b/src/ext/cmc/linkedlist.h @@ -21,587 +21,547 @@ /** * ITER */ -#define CMC_EXT_CMC_LINKEDLIST_ITER(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_ITER(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) #define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(PFX, SNAME, V) \ - \ - /* LinkedList Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target Linked List */ \ - struct SNAME *target; \ - \ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ - \ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* LinkedList Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target Linked List */ \ + struct SNAME *target; \ +\ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter); + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(PFX, SNAME, V) \ - \ +#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(PFX, SNAME, V) \ +\ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->head; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = target->tail; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.index = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->head; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->tail; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor->next == NULL) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = iter->cursor->next; \ - iter->index++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor->prev == NULL) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor = iter->cursor->prev; \ - iter->index--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor->next == NULL) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index += steps; \ - \ - for (size_t i = 0; i < steps; i++) \ - iter->cursor = iter->cursor->next; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor->prev == NULL) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->index < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->index -= steps; \ - \ - for (size_t i = 0; i < steps; i++) \ - iter->cursor = iter->cursor->prev; \ - \ - return true; \ - } \ - \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->head; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->tail; \ + iter.index = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + iter.index = target->count - 1; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->head; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->tail; \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor->next == NULL) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor = iter->cursor->next; \ + iter->index++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor->prev == NULL) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor = iter->cursor->prev; \ + iter->index--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor->next == NULL) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->index += steps; \ +\ + for (size_t i = 0; i < steps; i++) \ + iter->cursor = iter->cursor->next; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor->prev == NULL) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->index -= steps; \ +\ + for (size_t i = 0; i < steps; i++) \ + iter->cursor = iter->cursor->prev; \ +\ + return true; \ + } \ +\ /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->cursor->value; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->cursor->value); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->cursor->value; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->cursor->value); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ } /** * NODE */ -#define CMC_EXT_CMC_LINKEDLIST_NODE(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_NODE(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) #define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(PFX, SNAME, V) \ - \ - /* Node Allocation and Deallocation */ \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \ - void CMC_(PFX, _free_node)(struct SNAME * _list_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - /* Node Access Relative to a Linked List */ \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \ - /* Input and Output Relative to a Node */ \ - bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value); \ - bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value); \ - bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_); \ - /* Node Access Relative to a Linked List Node */ \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_); +#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(PFX, SNAME, V) \ +\ + /* Node Allocation and Deallocation */ \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \ + void CMC_(PFX, _free_node)(struct SNAME * _list_, struct CMC_DEF_NODE(SNAME) * _node_); \ + /* Node Access Relative to a Linked List */ \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \ + /* Input and Output Relative to a Node */ \ + bool CMC_(PFX, _add_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value); \ + bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value); \ + bool CMC_(PFX, _del_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \ + bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \ + bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \ + /* Node Access Relative to a Linked List Node */ \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_); -#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(PFX, SNAME, V) \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = \ - _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ - \ - if (!_node_) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - _node_->value = value; \ - _node_->next = NULL; \ - _node_->prev = NULL; \ - \ - return _node_; \ - } \ - \ - void CMC_(PFX, _free_node)(struct SNAME * _list_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - _list_->alloc->free(_node_); \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \ - { \ - return _list_->head; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ - \ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \ - \ - if (index <= _list_->count / 2) \ - { \ - _node_ = _list_->head; \ - for (size_t i = 0; i < index; i++) \ - { \ - _node_ = _node_->next; \ - } \ - } \ - else \ - { \ - _node_ = _list_->tail; \ - for (size_t i = _list_->count - 1; i > index; i--) \ - { \ - _node_ = _node_->prev; \ - } \ - } \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - return _node_; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \ - { \ - return _list_->tail; \ - } \ - \ - bool CMC_(PFX, _add_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *new_node = \ - CMC_(PFX, _new_node)(_owner_, value); \ - \ - if (!new_node) \ - return false; \ - \ - new_node->next = _node_->next; \ - \ - if (_node_->next != NULL) \ - _node_->next->prev = new_node; \ - else \ - _owner_->tail = new_node; \ - \ - new_node->prev = _node_; \ - _node_->next = new_node; \ - \ - _owner_->count++; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *new_node = \ - CMC_(PFX, _new_node)(_owner_, value); \ - \ - if (!new_node) \ - return false; \ - \ - new_node->prev = _node_->prev; \ - \ - if (_node_->prev != NULL) \ - _node_->prev->next = new_node; \ - else \ - _owner_->head = new_node; \ - \ - new_node->next = _node_; \ - _node_->prev = new_node; \ - \ - _owner_->count++; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_next)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->next == NULL) \ - { \ - _owner_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \ - \ - _node_->next = _node_->next->next; \ - \ - if (tmp->next != NULL) \ - tmp->next->prev = _node_; \ - else \ - _owner_->tail = _node_; \ - \ - _owner_->alloc->free(tmp); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->prev != NULL) \ - _node_->prev->next = _node_->next; \ - else \ - _owner_->head = _node_->next; \ - \ - if (_node_->next != NULL) \ - _node_->next->prev = _node_->prev; \ - else \ - _owner_->tail = _node_->prev; \ - \ - _owner_->alloc->free(_node_); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, \ - struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->prev == NULL) \ - { \ - _owner_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \ - \ - _node_->prev = _node_->prev->prev; \ - \ - if (tmp->prev != NULL) \ - tmp->prev->next = _node_; \ - else \ - _owner_->head = _node_; \ - \ - _owner_->alloc->free(tmp); \ - \ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ - \ - return true; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - return _node_->next; \ - } \ - \ - struct CMC_DEF_NODE(SNAME) * \ - CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - return _node_->prev; \ +#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(PFX, SNAME, V) \ +\ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *_node_ = _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ +\ + if (!_node_) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + _node_->value = value; \ + _node_->next = NULL; \ + _node_->prev = NULL; \ +\ + return _node_; \ + } \ +\ + void CMC_(PFX, _free_node)(struct SNAME * _list_, struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + _list_->alloc->free(_node_); \ + } \ +\ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \ + { \ + return _list_->head; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + { \ + _list_->flag = CMC_FLAG_EMPTY; \ + return NULL; \ + } \ +\ + if (index >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \ +\ + if (index <= _list_->count / 2) \ + { \ + _node_ = _list_->head; \ + for (size_t i = 0; i < index; i++) \ + { \ + _node_ = _node_->next; \ + } \ + } \ + else \ + { \ + _node_ = _list_->tail; \ + for (size_t i = _list_->count - 1; i > index; i--) \ + { \ + _node_ = _node_->prev; \ + } \ + } \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + return _node_; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \ + { \ + return _list_->tail; \ + } \ +\ + bool CMC_(PFX, _add_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *new_node = CMC_(PFX, _new_node)(_owner_, value); \ +\ + if (!new_node) \ + return false; \ +\ + new_node->next = _node_->next; \ +\ + if (_node_->next != NULL) \ + _node_->next->prev = new_node; \ + else \ + _owner_->tail = new_node; \ +\ + new_node->prev = _node_; \ + _node_->next = new_node; \ +\ + _owner_->count++; \ + _owner_->flag = CMC_FLAG_OK; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value) \ + { \ + struct CMC_DEF_NODE(SNAME) *new_node = CMC_(PFX, _new_node)(_owner_, value); \ +\ + if (!new_node) \ + return false; \ +\ + new_node->prev = _node_->prev; \ +\ + if (_node_->prev != NULL) \ + _node_->prev->next = new_node; \ + else \ + _owner_->head = new_node; \ +\ + new_node->next = _node_; \ + _node_->prev = new_node; \ +\ + _owner_->count++; \ + _owner_->flag = CMC_FLAG_OK; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _del_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->next == NULL) \ + { \ + _owner_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \ +\ + _node_->next = _node_->next->next; \ +\ + if (tmp->next != NULL) \ + tmp->next->prev = _node_; \ + else \ + _owner_->tail = _node_; \ +\ + _owner_->alloc->free(tmp); \ +\ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->prev != NULL) \ + _node_->prev->next = _node_->next; \ + else \ + _owner_->head = _node_->next; \ +\ + if (_node_->next != NULL) \ + _node_->next->prev = _node_->prev; \ + else \ + _owner_->tail = _node_->prev; \ +\ + _owner_->alloc->free(_node_); \ +\ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + if (_node_->prev == NULL) \ + { \ + _owner_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \ +\ + _node_->prev = _node_->prev->prev; \ +\ + if (tmp->prev != NULL) \ + tmp->prev->next = _node_; \ + else \ + _owner_->head = _node_; \ +\ + _owner_->alloc->free(tmp); \ +\ + _owner_->count--; \ + _owner_->flag = CMC_FLAG_OK; \ +\ + return true; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + return _node_->next; \ + } \ +\ + struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ + { \ + return _node_->prev; \ } /** * STR */ -#define CMC_EXT_CMC_LINKEDLIST_STR(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_STR(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) #define CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_STR_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ - const char *start, const char *separator, \ +#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ const char *end); -#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ - { \ - struct SNAME *l_ = _list_; \ - \ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "count:%" PRIuMAX ", " \ - "head:%p, " \ - "tail:%p, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, \ - l_->count, l_->head, l_->tail, l_->flag, \ - l_->f_val, l_->alloc, l_->callbacks); \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ - const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ - \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ - \ - while (scan != NULL) \ - { \ - if (!_list_->f_val->str(fptr, scan->value)) \ - return false; \ - \ - scan = scan->next; \ - \ - if (scan) \ - fprintf(fptr, "%s", separator); \ - } \ - \ - fprintf(fptr, "%s", end); \ - \ - return true; \ +#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ + { \ + struct SNAME *l_ = _list_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "count:%" PRIuMAX ", " \ + "head:%p, " \ + "tail:%p, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->count, l_->head, l_->tail, l_->flag, \ + l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ +\ + while (scan != NULL) \ + { \ + if (!_list_->f_val->str(fptr, scan->value)) \ + return false; \ +\ + scan = scan->next; \ +\ + if (scan) \ + fprintf(fptr, "%s", separator); \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ } #endif /* CMC_EXT_CMC_LINKEDLIST_H */ diff --git a/src/ext/cmc/list.h b/src/ext/cmc/list.h index 155d6d7..e7e3160 100644 --- a/src/ext/cmc/list.h +++ b/src/ext/cmc/list.h @@ -21,507 +21,476 @@ /** * ITER */ -#define CMC_EXT_CMC_LIST_ITER(PARAMS) \ +#define CMC_EXT_CMC_LIST_ITER(PARAMS) \ CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \ CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) #define CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_ITER_HEADER_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_LIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_ITER_SOURCE_( \ - CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + CMC_EXT_CMC_LIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LIST_ITER_HEADER_(PFX, SNAME, V) \ - \ - /* List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target List */ \ - struct SNAME *target; \ - \ - /* Cursor's position (index) */ \ - size_t cursor; \ - \ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ - \ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ - \ - /* Iterator Initialization */ \ +#define CMC_EXT_CMC_LIST_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* List Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target List */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); -#define CMC_EXT_CMC_LIST_ITER_SOURCE_(PFX, SNAME, V) \ - \ +#define CMC_EXT_CMC_LIST_ITER_SOURCE_(PFX, SNAME, V) \ +\ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ - \ - return iter; \ - } \ - \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ - \ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ - \ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ - \ - return iter; \ - } \ - \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ - \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ - \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->target->count - 1; \ - iter->end = true; \ - \ - return true; \ - } \ - \ - return false; \ - } \ - \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor++; \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor--; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->end) \ - return false; \ - \ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ - \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor += steps; \ - \ - return true; \ - } \ - \ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t steps) \ - { \ - if (iter->start) \ - return false; \ - \ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ - \ - if (steps == 0 || iter->cursor < steps) \ - return false; \ - \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - \ - iter->cursor -= steps; \ - \ - return true; \ - } \ - \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->target->count - 1; \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor += steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, \ - size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ - \ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ - \ - return true; \ - } \ - \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ - \ - return iter->target->buffer[iter->cursor]; \ - } \ - \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ - \ - return &(iter->target->buffer[iter->cursor]); \ - } \ - \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->target->buffer[iter->cursor]); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ } /** * SEQ */ -#define CMC_EXT_CMC_LIST_SEQ(PARAMS) \ +#define CMC_EXT_CMC_LIST_SEQ(PARAMS) \ CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \ CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) -#define CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_SEQ_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_SEQ_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_SEQ_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LIST_SEQ_HEADER_(PFX, SNAME, V) \ - \ - /* List Sequence Input and Output */ \ - bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ - size_t size); \ - bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ - size_t size, size_t index); \ - bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ - size_t size); \ - bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, \ - size_t to); \ - struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ - size_t to); +#define CMC_EXT_CMC_LIST_SEQ_HEADER_(PFX, SNAME, V) \ +\ + /* List Sequence Input and Output */ \ + bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, size_t size); \ + bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, size_t size, size_t index); \ + bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, size_t size); \ + bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to); \ + struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, size_t to); -#define CMC_EXT_CMC_LIST_SEQ_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, \ - size_t size) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + size, _list_->buffer, \ - _list_->count * sizeof(V)); \ - \ - memcpy(_list_->buffer, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, \ - size_t size, size_t index) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - if (index == 0) \ - return CMC_(PFX, _seq_push_front)(_list_, values, size); \ - else if (index == _list_->count) \ - return CMC_(PFX, _seq_push_back)(_list_, values, size); \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memmove(_list_->buffer + index + size, _list_->buffer + index, \ - (_list_->count - index) * sizeof(V)); \ - \ - memcpy(_list_->buffer + index, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ - bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, \ - size_t size) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ - \ - memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \ - \ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ - \ - return true; \ - } \ - \ +#define CMC_EXT_CMC_LIST_SEQ_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, size_t size) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ +\ + memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(V)); \ +\ + memcpy(_list_->buffer, values, size * sizeof(V)); \ +\ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, size_t size, size_t index) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + if (index > _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ +\ + if (index == 0) \ + return CMC_(PFX, _seq_push_front)(_list_, values, size); \ + else if (index == _list_->count) \ + return CMC_(PFX, _seq_push_back)(_list_, values, size); \ +\ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ +\ + memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \ +\ + memcpy(_list_->buffer + index, values, size * sizeof(V)); \ +\ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, size_t size) \ + { \ + if (size == 0) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + if (!CMC_(PFX, _fits)(_list_, size)) \ + { \ + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ + return false; \ + } \ +\ + memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \ +\ + _list_->count += size; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->create) \ + _list_->callbacks->create(); \ +\ + return true; \ + } \ +\ bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \ - { \ - if (from > to) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ - \ - if (to >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ - \ - size_t length = (to - from + 1); \ - \ - memmove(_list_->buffer + from, _list_->buffer + to + 1, \ - (_list_->count - to - 1) * sizeof(V)); \ - \ - memset(_list_->buffer + _list_->count - length, 0, \ - length * sizeof(V)); \ - \ - _list_->count -= to - from + 1; \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return true; \ - } \ - \ - struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, \ - size_t to) \ - { \ - if (from > to) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return NULL; \ - } \ - \ - if (to >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ - \ - size_t length = to - from + 1; \ - \ - struct SNAME *result = CMC_(PFX, _new_custom)( \ - length, _list_->f_val, _list_->alloc, _list_->callbacks); \ - \ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ - \ - memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \ - \ - memmove(_list_->buffer + from, _list_->buffer + to + 1, \ - (_list_->count - to - 1) * sizeof(V)); \ - \ - memset(_list_->buffer + _list_->count - length, 0, \ - length * sizeof(V)); \ - \ - _list_->count -= length; \ - result->count = length; \ - \ - _list_->flag = CMC_FLAG_OK; \ - \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ - \ - return result; \ + { \ + if (from > to) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return false; \ + } \ +\ + if (to >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return false; \ + } \ +\ + size_t length = (to - from + 1); \ +\ + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); \ +\ + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \ +\ + _list_->count -= to - from + 1; \ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return true; \ + } \ +\ + struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, size_t to) \ + { \ + if (from > to) \ + { \ + _list_->flag = CMC_FLAG_INVALID; \ + return NULL; \ + } \ +\ + if (to >= _list_->count) \ + { \ + _list_->flag = CMC_FLAG_RANGE; \ + return NULL; \ + } \ +\ + size_t length = to - from + 1; \ +\ + struct SNAME *result = CMC_(PFX, _new_custom)(length, _list_->f_val, _list_->alloc, _list_->callbacks); \ +\ + if (!result) \ + { \ + _list_->flag = CMC_FLAG_ALLOC; \ + return NULL; \ + } \ +\ + memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \ +\ + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); \ +\ + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \ +\ + _list_->count -= length; \ + result->count = length; \ +\ + _list_->flag = CMC_FLAG_OK; \ +\ + if (_list_->callbacks && _list_->callbacks->delete) \ + _list_->callbacks->delete (); \ +\ + return result; \ } /** * STR */ -#define CMC_EXT_CMC_LIST_STR(PARAMS) \ +#define CMC_EXT_CMC_LIST_STR(PARAMS) \ CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \ CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) -#define CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), \ - CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +#define CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LIST_STR_HEADER_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ - const char *start, const char *separator, \ +#define CMC_EXT_CMC_LIST_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ const char *end); -#define CMC_EXT_CMC_LIST_STR_SOURCE_(PFX, SNAME, V) \ - \ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ - { \ - struct SNAME *l_ = _list_; \ - \ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, \ - l_->buffer, l_->capacity, l_->count, l_->flag, \ - l_->f_val, l_->alloc, l_->callbacks); \ - } \ - \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, \ - const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ - \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ - return false; \ - \ - if (i + 1 < _list_->count) \ - fprintf(fptr, "%s", separator); \ - } \ - \ - fprintf(fptr, "%s", end); \ - \ - return true; \ +#define CMC_EXT_CMC_LIST_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ + { \ + struct SNAME *l_ = _list_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->buffer, l_->capacity, l_->count, l_->flag, \ + l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ + return false; \ +\ + if (i + 1 < _list_->count) \ + fprintf(fptr, "%s", separator); \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ } #endif /* CMC_EXT_CMC_LIST_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 50bb4a2..12d0b92 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -86,8 +86,7 @@ */ #define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE)(PARAMS) -#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE) \ - CMC_##LIB##_##COLLECTION##_##PART##_##FILE +#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE) CMC_##LIB##_##COLLECTION##_##PART##_##FILE /** * C_MACRO_COLLECTIONS_GEN @@ -100,7 +99,7 @@ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) * \param PARTS A non-empty tuple of all desired EXT parts */ -#define C_MACRO_COLLECTIONS_GEN(LIB, COLLECTION, PARAMS, PARTS) \ +#define C_MACRO_COLLECTIONS_GEN(LIB, COLLECTION, PARAMS, PARTS) \ C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \ C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) @@ -115,7 +114,7 @@ * \param PARTS A non-empty tuple of all desired EXT parts */ #define C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, CMC_EVAL PARTS) /** @@ -129,7 +128,7 @@ * \param PARTS A non-empty tuple of all desired EXT parts */ #define C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, CMC_EVAL PARTS) /** @@ -142,7 +141,7 @@ * \param COLLECTION The name of the collection in all uppercase * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V */ -#define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \ +#define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \ C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \ C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) @@ -156,9 +155,8 @@ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V */ #define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, \ - C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) /** * C_MACRO_COLLECTIONS_ALL_SOURCE @@ -170,9 +168,8 @@ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V */ #define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, \ - C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) /** * C_MACRO_COLLECTIONS_PARTS @@ -180,8 +177,7 @@ * Gets the macro with all EXT parts of a collection. Every collection has this * macro defined in the EXT libraries. */ -#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) \ - CMC_EXT_##LIB##_##COLLECTION##_PARTS, +#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) CMC_EXT_##LIB##_##COLLECTION##_PARTS, /* Evaluates a tuple so that (A, B) -> A, B, */ #define CMC_EVAL(...) __VA_ARGS__, @@ -195,50 +191,47 @@ */ #define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N()) #define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__) -#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ - _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, \ - _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ - _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ - _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ - _62, _63, N, ...) \ +#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, \ + _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, \ + _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ + _62, _63, N, ...) \ N -#define CMC_SEQ_N() \ - 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \ - 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \ - 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +#define CMC_SEQ_N() \ + 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, \ + 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, \ + 7, 6, 5, 4, 3, 2, 1, 0 /* Generates the FILE for each part (__VA_ARGS__) of a collection */ #define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \ - CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \ + CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \ (LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) #define CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, PART, ...) -#define CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ +#define CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) #define CMC_MAP_10(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ diff --git a/src/utl/assert.h b/src/utl/assert.h index c63883c..110acb6 100644 --- a/src/utl/assert.h +++ b/src/utl/assert.h @@ -89,19 +89,18 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; /** * expression : An expression that is expected to be evaluated to true. */ -#define cmc_assert(expression) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #expression; \ - if (!(expression)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }\n", \ - __FILE__, __func__, __LINE__, str); \ - } \ +#define cmc_assert(expression) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #expression; \ + if (!(expression)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }\n", __FILE__, __func__, __LINE__, str); \ + } \ } while (0) /** @@ -110,7 +109,7 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * actual : Actual value tested against 'expected'. */ #define cmc_assert_equals(dtype, expected, actual) \ - CMC_ASSERT_GLUE(dtype, equals) \ + CMC_ASSERT_GLUE(dtype, equals) \ (expected, actual) /** @@ -119,7 +118,7 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * actual : Actual value tested against 'not_expected'. */ #define cmc_assert_not_equals(dtype, not_expected, actual) \ - CMC_ASSERT_GLUE(dtype, not_equals) \ + CMC_ASSERT_GLUE(dtype, not_equals) \ (not_expected, actual) /** @@ -128,7 +127,7 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * actual : Actual value tested against the given boundary. */ #define cmc_assert_greater(dtype, boundary, actual) \ - CMC_ASSERT_GLUE(dtype, greater) \ + CMC_ASSERT_GLUE(dtype, greater) \ (boundary, actual) /** @@ -137,7 +136,7 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * actual : Actual value tested against the given boundary. */ #define cmc_assert_greater_equals(dtype, boundary, actual) \ - CMC_ASSERT_GLUE(dtype, greater_equals) \ + CMC_ASSERT_GLUE(dtype, greater_equals) \ (boundary, actual) /** @@ -146,7 +145,7 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * actual : Actual value tested against the given boundary. */ #define cmc_assert_lesser(dtype, boundary, actual) \ - CMC_ASSERT_GLUE(dtype, lesser) \ + CMC_ASSERT_GLUE(dtype, lesser) \ (boundary, actual) /** @@ -155,7 +154,7 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * actual : Actual value tested against the given boundary. */ #define cmc_assert_lesser_equals(dtype, boundary, actual) \ - CMC_ASSERT_GLUE(dtype, lesser_equals) \ + CMC_ASSERT_GLUE(dtype, lesser_equals) \ (boundary, actual) /** @@ -167,7 +166,7 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * Range is inclusive on both ends. */ #define cmc_assert_in_range(dtype, lower_bound, upper_bound, actual) \ - CMC_ASSERT_GLUE(dtype, in_range) \ + CMC_ASSERT_GLUE(dtype, in_range) \ (lower_bound, upper_bound, actual) /** @@ -179,7 +178,7 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * Range is inclusive on both ends. */ #define cmc_assert_not_in_range(dtype, lower_bound, upper_bound, actual) \ - CMC_ASSERT_GLUE(dtype, not_in_range) \ + CMC_ASSERT_GLUE(dtype, not_in_range) \ (lower_bound, upper_bound, actual) /** --------------------------------------------------------------------------- @@ -202,36 +201,35 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * This macro can be used for any data type. Both bounds are inclusive. */ -#define cmc_assert_array_equals_any(dtype, array1, array2, comparator, \ - from_index, to_index) \ - do \ - { \ - cmc_assert_total++; \ - const char *str1__ = #array1; \ - const char *str2__ = #array2; \ - dtype *arr1__ = array1; \ - dtype *arr2__ = array2; \ - size_t from__ = from_index; \ - size_t to__ = to_index; \ - int (*cmp__)(dtype, dtype) = comparator; \ - \ - for (size_t i__ = from__; i__ <= to__; i__++) \ - { \ - if (cmp__(arr1__[i__], arr2__[i__]) != 0) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ +#define cmc_assert_array_equals_any(dtype, array1, array2, comparator, from_index, to_index) \ + do \ + { \ + cmc_assert_total++; \ + const char *str1__ = #array1; \ + const char *str2__ = #array2; \ + dtype *arr1__ = array1; \ + dtype *arr2__ = array2; \ + size_t from__ = from_index; \ + size_t to__ = to_index; \ + int (*cmp__)(dtype, dtype) = comparator; \ +\ + for (size_t i__ = from__; i__ <= to__; i__++) \ + { \ + if (cmp__(arr1__[i__], arr2__[i__]) != 0) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf( \ + stderr, \ "Assertion Failed at %s:%s:%u for { %s and %s }: Arrays values are not equal at index %" PRIuMAX \ - "\n", \ - __FILE__, __func__, __LINE__, str1__, str2__, i__); \ - \ - break; \ - } \ - } \ - \ + "\n", \ + __FILE__, __func__, __LINE__, str1__, str2__, i__); \ +\ + break; \ + } \ + } \ +\ } while (0) /** @@ -249,37 +247,34 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * This macro can be used for any data type. Both bounds are inclusive. */ -#define cmc_assert_array_within_any(dtype, array, comparator, lower_bound, \ - upper_bound, from_index, to_index) \ - do \ - { \ - cmc_assert_total++; \ - const char *str__ = #array; \ - dtype *arr__ = array; \ - dtype lower_bound___ = lower_bound; \ - dtype upper_bound___ = upper_bound; \ - size_t from__ = from_index; \ - size_t to__ = to_index; \ - int (*cmp__)(dtype, dtype) = comparator; \ - \ - for (size_t i__ = from__; i__ <= to__; i__++) \ - { \ - if (cmp__(arr__[i__], lower_bound___) < 0 || \ - cmp__(arr__[i__], upper_bound___) > 0) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Array value not within bounds at index %" PRIuMAX \ - "\n", \ - __FILE__, __func__, __LINE__, str__, i__); \ - \ - break; \ - } \ - } \ - \ +#define cmc_assert_array_within_any(dtype, array, comparator, lower_bound, upper_bound, from_index, to_index) \ + do \ + { \ + cmc_assert_total++; \ + const char *str__ = #array; \ + dtype *arr__ = array; \ + dtype lower_bound___ = lower_bound; \ + dtype upper_bound___ = upper_bound; \ + size_t from__ = from_index; \ + size_t to__ = to_index; \ + int (*cmp__)(dtype, dtype) = comparator; \ +\ + for (size_t i__ = from__; i__ <= to__; i__++) \ + { \ + if (cmp__(arr__[i__], lower_bound___) < 0 || cmp__(arr__[i__], upper_bound___) > 0) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Array value not within bounds at index %" PRIuMAX \ + "\n", \ + __FILE__, __func__, __LINE__, str__, i__); \ +\ + break; \ + } \ + } \ +\ } while (0) /** @@ -297,37 +292,34 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * This macro can be used for any data type. Both bounds are inclusive. */ -#define cmc_assert_array_outside_any(dtype, array, comparator, lower_bound, \ - upper_bound, from_index, to_index) \ - do \ - { \ - cmc_assert_total++; \ - const char *str__ = #array; \ - dtype *arr__ = array; \ - dtype lower_bound___ = lower_bound; \ - dtype upper_bound___ = upper_bound; \ - size_t from__ = from_index; \ - size_t to__ = to_index; \ - int (*cmp__)(dtype, dtype) = comparator; \ - \ - for (size_t i__ = from__; i__ <= to__; i__++) \ - { \ - if (cmp__(arr__[i__], lower_bound___) >= 0 && \ - cmp__(arr__[i__], upper_bound___) <= 0) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Array value not outside bounds at index %" PRIuMAX \ - "\n", \ - __FILE__, __func__, __LINE__, str__, i__); \ - \ - break; \ - } \ - } \ - \ +#define cmc_assert_array_outside_any(dtype, array, comparator, lower_bound, upper_bound, from_index, to_index) \ + do \ + { \ + cmc_assert_total++; \ + const char *str__ = #array; \ + dtype *arr__ = array; \ + dtype lower_bound___ = lower_bound; \ + dtype upper_bound___ = upper_bound; \ + size_t from__ = from_index; \ + size_t to__ = to_index; \ + int (*cmp__)(dtype, dtype) = comparator; \ +\ + for (size_t i__ = from__; i__ <= to__; i__++) \ + { \ + if (cmp__(arr__[i__], lower_bound___) >= 0 && cmp__(arr__[i__], upper_bound___) <= 0) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Array value not outside bounds at index %" PRIuMAX \ + "\n", \ + __FILE__, __func__, __LINE__, str__, i__); \ +\ + break; \ + } \ + } \ +\ } while (0) /** @@ -343,38 +335,36 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * This macro can be used for any data type. */ -#define cmc_assert_array_sorted_any(dtype, array, comparator, from_index, \ - to_index) \ - do \ - { \ - cmc_assert_total++; \ - const char *str__ = #array; \ - dtype *arr__ = array; \ - size_t from__ = from_index; \ - size_t to__ = to_index; \ - int (*cmp__)(dtype, dtype) = comparator; \ - \ - size_t iprev__ = from__; \ - \ - for (size_t i__ = from__ + 1; i__ <= to__; i__++) \ - { \ - if (cmp__(arr__[iprev__], arr__[i__]) > 0) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not sorted when comparing indexes %" PRIuMAX \ - " and %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str__, iprev__, i__); \ - \ - break; \ - } \ - \ - iprev__ = i__; \ - } \ - \ +#define cmc_assert_array_sorted_any(dtype, array, comparator, from_index, to_index) \ + do \ + { \ + cmc_assert_total++; \ + const char *str__ = #array; \ + dtype *arr__ = array; \ + size_t from__ = from_index; \ + size_t to__ = to_index; \ + int (*cmp__)(dtype, dtype) = comparator; \ +\ + size_t iprev__ = from__; \ +\ + for (size_t i__ = from__ + 1; i__ <= to__; i__++) \ + { \ + if (cmp__(arr__[iprev__], arr__[i__]) > 0) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not sorted when comparing indexes %" PRIuMAX \ + " and %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str__, iprev__, i__); \ +\ + break; \ + } \ +\ + iprev__ = i__; \ + } \ +\ } while (0) /** --------------------------------------------------------------------------- @@ -383,330 +373,289 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * ------------------------------------------------------------------------ **/ -#define cmc_assert_equals_int8_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int8_t expected__ = (expected); \ - int8_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId8 \ - " Actual: %" PRId8 "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_int8_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int8_t expected__ = (expected); \ + int8_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId8 " Actual: %" PRId8 "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_int16_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int16_t expected__ = (expected); \ - int16_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId16 \ - " Actual: %" PRId16 "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_int16_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int16_t expected__ = (expected); \ + int16_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId16 " Actual: %" PRId16 "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_int32_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int32_t expected__ = (expected); \ - int32_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId32 \ - " Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_int32_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int32_t expected__ = (expected); \ + int32_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId32 " Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_int64_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int64_t expected__ = (expected); \ - int64_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId64 \ - " Actual: %" PRId64 "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_int64_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int64_t expected__ = (expected); \ + int64_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId64 " Actual: %" PRId64 "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_uint8_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint8_t expected__ = (expected); \ - uint8_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu8 \ - " Actual: %" PRIu8 "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_uint8_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint8_t expected__ = (expected); \ + uint8_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu8 " Actual: %" PRIu8 "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_uint16_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint16_t expected__ = (expected); \ - uint16_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu16 \ - " Actual: %" PRIu16 "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_uint16_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint16_t expected__ = (expected); \ + uint16_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu16 " Actual: %" PRIu16 "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_uint32_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint32_t expected__ = (expected); \ - uint32_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu32 \ - " Actual: %" PRIu32 "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_uint32_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint32_t expected__ = (expected); \ + uint32_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu32 " Actual: %" PRIu32 "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_uint64_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint64_t expected__ = (expected); \ - uint64_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu64 \ - " Actual: %" PRIu64 "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_uint64_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint64_t expected__ = (expected); \ + uint64_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu64 " Actual: %" PRIu64 "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_intmax_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - intmax_t expected__ = (expected); \ - intmax_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIdMAX \ - " Actual: %" PRIdMAX "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_intmax_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + intmax_t expected__ = (expected); \ + intmax_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIdMAX " Actual: %" PRIdMAX "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_uintmax_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uintmax_t expected__ = (expected); \ - uintmax_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_uintmax_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uintmax_t expected__ = (expected); \ + uintmax_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_size_t(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - size_t expected__ = (expected); \ - size_t actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_size_t(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + size_t expected__ = (expected); \ + size_t actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_float(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - float expected__ = (expected); \ - float actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %f Actual: %f\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_float(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + float expected__ = (expected); \ + float actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %f Actual: %f\n", __FILE__, __func__, \ + __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_double(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - double expected__ = (expected); \ - double actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %lf Actual: %lf\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_double(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + double expected__ = (expected); \ + double actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %lf Actual: %lf\n", __FILE__, \ + __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals_ptr(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - void *expected__ = (expected); \ - void *actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %p Actual: %p\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals_ptr(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + void *expected__ = (expected); \ + void *actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %p Actual: %p\n", __FILE__, __func__, \ + __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_equals__Bool(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - bool expected__ = (expected); \ - bool actual__ = (actual); \ - \ - if (expected__ != actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected: %d Actual: %d\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_equals__Bool(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + bool expected__ = (expected); \ + bool actual__ = (actual); \ +\ + if (expected__ != actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %d Actual: %d\n", __FILE__, __func__, \ + __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) /** --------------------------------------------------------------------------- @@ -715,329 +664,297 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * ------------------------------------------------------------------------ **/ -#define cmc_assert_not_equals_int8_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int8_t not_expected__ = (not_expected); \ - int8_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId8 \ - " Actual: %" PRId8 "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_int8_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int8_t not_expected__ = (not_expected); \ + int8_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId8 " Actual: %" PRId8 "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_int16_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int16_t not_expected__ = (not_expected); \ - int16_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId16 \ - " Actual: %" PRId16 "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_int16_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int16_t not_expected__ = (not_expected); \ + int16_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId16 " Actual: %" PRId16 "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_int32_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int32_t not_expected__ = (not_expected); \ - int32_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId32 \ - " Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_int32_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int32_t not_expected__ = (not_expected); \ + int32_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId32 " Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_int64_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int64_t not_expected__ = (not_expected); \ - int64_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId64 \ - " Actual: %" PRId64 "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_int64_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int64_t not_expected__ = (not_expected); \ + int64_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId64 " Actual: %" PRId64 "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_uint8_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint8_t not_expected__ = (not_expected); \ - uint8_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu8 \ - " Actual: %" PRIu8 "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_uint8_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint8_t not_expected__ = (not_expected); \ + uint8_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu8 " Actual: %" PRIu8 "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_uint16_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint16_t not_expected__ = (not_expected); \ - uint16_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu16 \ - " Actual: %" PRIu16 "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_uint16_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint16_t not_expected__ = (not_expected); \ + uint16_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu16 " Actual: %" PRIu16 "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_uint32_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint32_t not_expected__ = (not_expected); \ - uint32_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu32 \ - " Actual: %" PRIu32 "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_uint32_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint32_t not_expected__ = (not_expected); \ + uint32_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu32 " Actual: %" PRIu32 "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_uint64_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint64_t not_expected__ = (not_expected); \ - uint64_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu64 \ - " Actual: %" PRIu64 "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_uint64_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint64_t not_expected__ = (not_expected); \ + uint64_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu64 " Actual: %" PRIu64 "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_intmax_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - intmax_t not_expected__ = (not_expected); \ - intmax_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIdMAX \ - " Actual: %" PRIdMAX "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_intmax_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + intmax_t not_expected__ = (not_expected); \ + intmax_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIdMAX " Actual: %" PRIdMAX "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_uintmax_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uintmax_t not_expected__ = (not_expected); \ - uintmax_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_uintmax_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uintmax_t not_expected__ = (not_expected); \ + uintmax_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_size_t(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - size_t not_expected__ = (not_expected); \ - size_t actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_size_t(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + size_t not_expected__ = (not_expected); \ + size_t actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_float(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - float not_expected__ = (not_expected); \ - float actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %f Actual: %f\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_float(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + float not_expected__ = (not_expected); \ + float actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %f Actual: %f\n", __FILE__, \ + __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_double(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - double not_expected__ = (not_expected); \ - double actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %lf Actual: %lf\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_double(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + double not_expected__ = (not_expected); \ + double actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %lf Actual: %lf\n", __FILE__, \ + __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals_ptr(not_expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - void *not_expected__ = (not_expected); \ - void *actual__ = (actual); \ - \ - if (not_expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %p Actual: %p\n", \ - __FILE__, __func__, __LINE__, str, not_expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals_ptr(not_expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + void *not_expected__ = (not_expected); \ + void *actual__ = (actual); \ +\ + if (not_expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %p Actual: %p\n", __FILE__, \ + __func__, __LINE__, str, not_expected__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_equals__Bool(expected, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - bool expected__ = (expected); \ - bool actual__ = (actual); \ - \ - if (expected__ == actual__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %d Actual: %d\n", \ - __FILE__, __func__, __LINE__, str, expected__, actual__); \ - } \ - \ +#define cmc_assert_not_equals__Bool(expected, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + bool expected__ = (expected); \ + bool actual__ = (actual); \ +\ + if (expected__ == actual__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %d Actual: %d\n", __FILE__, \ + __func__, __LINE__, str, expected__, actual__); \ + } \ +\ } while (0) /** --------------------------------------------------------------------------- @@ -1046,288 +963,262 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * ------------------------------------------------------------------------ **/ -#define cmc_assert_greater_int8_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int8_t boundary__ = (boundary); \ - int8_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId8 \ - " Actual: %" PRId8 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_int8_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int8_t boundary__ = (boundary); \ + int8_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId8 " Actual: %" PRId8 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_int16_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int16_t boundary__ = (boundary); \ - int16_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId16 \ - " Actual: %" PRId16 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_int16_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int16_t boundary__ = (boundary); \ + int16_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId16 " Actual: %" PRId16 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_int32_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int32_t boundary__ = (boundary); \ - int32_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId32 \ - " Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_int32_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int32_t boundary__ = (boundary); \ + int32_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId32 " Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_int64_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int64_t boundary__ = (boundary); \ - int64_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId64 \ - " Actual: %" PRId64 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_int64_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int64_t boundary__ = (boundary); \ + int64_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId64 " Actual: %" PRId64 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_uint8_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint8_t boundary__ = (boundary); \ - uint8_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu8 \ - " Actual: %" PRIu8 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_uint8_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint8_t boundary__ = (boundary); \ + uint8_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu8 " Actual: %" PRIu8 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_uint16_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint16_t boundary__ = (boundary); \ - uint16_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu16 \ - " Actual: %" PRIu16 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_uint16_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint16_t boundary__ = (boundary); \ + uint16_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu16 " Actual: %" PRIu16 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_uint32_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint32_t boundary__ = (boundary); \ - uint32_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu32 \ - " Actual: %" PRIu32 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_uint32_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint32_t boundary__ = (boundary); \ + uint32_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu32 " Actual: %" PRIu32 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_uint64_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint64_t boundary__ = (boundary); \ - uint64_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu64 \ - " Actual: %" PRIu64 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_uint64_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint64_t boundary__ = (boundary); \ + uint64_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu64 " Actual: %" PRIu64 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_intmax_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - intmax_t boundary__ = (boundary); \ - intmax_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIdMAX \ - " Actual: %" PRIdMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_intmax_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + intmax_t boundary__ = (boundary); \ + intmax_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIdMAX " Actual: %" PRIdMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_uintmax_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uintmax_t boundary__ = (boundary); \ - uintmax_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_uintmax_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uintmax_t boundary__ = (boundary); \ + uintmax_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIuMAX " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_size_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - size_t boundary__ = (boundary); \ - size_t actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_size_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + size_t boundary__ = (boundary); \ + size_t actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIuMAX " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_float(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - float boundary__ = (boundary); \ - float actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %f Actual: %f\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_float(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + float boundary__ = (boundary); \ + float actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %f Actual: %f\n", __FILE__, \ + __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_double(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - double boundary__ = (boundary); \ - double actual__ = (actual); \ - \ - if (actual__ <= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %lf Actual: %lf\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_double(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + double boundary__ = (boundary); \ + double actual__ = (actual); \ +\ + if (actual__ <= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %lf Actual: %lf\n", __FILE__, \ + __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) /** --------------------------------------------------------------------------- @@ -1336,288 +1227,273 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * ------------------------------------------------------------------------ **/ -#define cmc_assert_greater_equals_int8_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int8_t boundary__ = (boundary); \ - int8_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId8 \ - " Actual: %" PRId8 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_int8_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int8_t boundary__ = (boundary); \ + int8_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId8 " Actual: %" PRId8 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_int16_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int16_t boundary__ = (boundary); \ - int16_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId16 \ - " Actual: %" PRId16 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_int16_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int16_t boundary__ = (boundary); \ + int16_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId16 \ + " Actual: %" PRId16 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_int32_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int32_t boundary__ = (boundary); \ - int32_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId32 \ - " Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_int32_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int32_t boundary__ = (boundary); \ + int32_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId32 \ + " Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_int64_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int64_t boundary__ = (boundary); \ - int64_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId64 \ - " Actual: %" PRId64 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_int64_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int64_t boundary__ = (boundary); \ + int64_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId64 \ + " Actual: %" PRId64 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_uint8_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint8_t boundary__ = (boundary); \ - uint8_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu8 \ - " Actual: %" PRIu8 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_uint8_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint8_t boundary__ = (boundary); \ + uint8_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu8 " Actual: %" PRIu8 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_uint16_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint16_t boundary__ = (boundary); \ - uint16_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu16 \ - " Actual: %" PRIu16 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_uint16_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint16_t boundary__ = (boundary); \ + uint16_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu16 \ + " Actual: %" PRIu16 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_uint32_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint32_t boundary__ = (boundary); \ - uint32_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu32 \ - " Actual: %" PRIu32 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_uint32_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint32_t boundary__ = (boundary); \ + uint32_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu32 \ + " Actual: %" PRIu32 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_uint64_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint64_t boundary__ = (boundary); \ - uint64_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu64 \ - " Actual: %" PRIu64 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_uint64_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint64_t boundary__ = (boundary); \ + uint64_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu64 \ + " Actual: %" PRIu64 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_intmax_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - intmax_t boundary__ = (boundary); \ - intmax_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIdMAX \ - " Actual: %" PRIdMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_intmax_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + intmax_t boundary__ = (boundary); \ + intmax_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIdMAX \ + " Actual: %" PRIdMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_uintmax_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uintmax_t boundary__ = (boundary); \ - uintmax_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_uintmax_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uintmax_t boundary__ = (boundary); \ + uintmax_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIuMAX \ + " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_size_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - size_t boundary__ = (boundary); \ - size_t actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_size_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + size_t boundary__ = (boundary); \ + size_t actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIuMAX \ + " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_float(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - float boundary__ = (boundary); \ - float actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %f Actual: %f\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_float(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + float boundary__ = (boundary); \ + float actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %f Actual: %f\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_greater_equals_double(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - double boundary__ = (boundary); \ - double actual__ = (actual); \ - \ - if (actual__ < boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %lf Actual: %lf\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_greater_equals_double(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + double boundary__ = (boundary); \ + double actual__ = (actual); \ +\ + if (actual__ < boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %lf Actual: %lf\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) /** --------------------------------------------------------------------------- @@ -1626,288 +1502,262 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * ------------------------------------------------------------------------ **/ -#define cmc_assert_lesser_int8_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int8_t boundary__ = (boundary); \ - int8_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId8 \ - " Actual: %" PRId8 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_int8_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int8_t boundary__ = (boundary); \ + int8_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId8 " Actual: %" PRId8 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_int16_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int16_t boundary__ = (boundary); \ - int16_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId16 \ - " Actual: %" PRId16 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_int16_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int16_t boundary__ = (boundary); \ + int16_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId16 " Actual: %" PRId16 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_int32_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int32_t boundary__ = (boundary); \ - int32_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId32 \ - " Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_int32_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int32_t boundary__ = (boundary); \ + int32_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId32 " Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_int64_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int64_t boundary__ = (boundary); \ - int64_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId64 \ - " Actual: %" PRId64 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_int64_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int64_t boundary__ = (boundary); \ + int64_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId64 " Actual: %" PRId64 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_uint8_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint8_t boundary__ = (boundary); \ - uint8_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu8 \ - " Actual: %" PRIu8 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_uint8_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint8_t boundary__ = (boundary); \ + uint8_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu8 " Actual: %" PRIu8 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_uint16_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint16_t boundary__ = (boundary); \ - uint16_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu16 \ - " Actual: %" PRIu16 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_uint16_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint16_t boundary__ = (boundary); \ + uint16_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu16 " Actual: %" PRIu16 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_uint32_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint32_t boundary__ = (boundary); \ - uint32_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu32 \ - " Actual: %" PRIu32 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_uint32_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint32_t boundary__ = (boundary); \ + uint32_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu32 " Actual: %" PRIu32 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_uint64_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint64_t boundary__ = (boundary); \ - uint64_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu64 \ - " Actual: %" PRIu64 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_uint64_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint64_t boundary__ = (boundary); \ + uint64_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu64 " Actual: %" PRIu64 "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_intmax_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - intmax_t boundary__ = (boundary); \ - intmax_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIdMAX \ - " Actual: %" PRIdMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_intmax_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + intmax_t boundary__ = (boundary); \ + intmax_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIdMAX " Actual: %" PRIdMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_uintmax_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uintmax_t boundary__ = (boundary); \ - uintmax_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_uintmax_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uintmax_t boundary__ = (boundary); \ + uintmax_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIuMAX " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_size_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - size_t boundary__ = (boundary); \ - size_t actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_size_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + size_t boundary__ = (boundary); \ + size_t actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIuMAX " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_float(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - float boundary__ = (boundary); \ - float actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %f Actual: %f\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_float(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + float boundary__ = (boundary); \ + float actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %f Actual: %f\n", __FILE__, \ + __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_double(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - double boundary__ = (boundary); \ - double actual__ = (actual); \ - \ - if (actual__ >= boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %lf Actual: %lf\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_double(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + double boundary__ = (boundary); \ + double actual__ = (actual); \ +\ + if (actual__ >= boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %lf Actual: %lf\n", __FILE__, \ + __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) /** --------------------------------------------------------------------------- @@ -1916,288 +1766,273 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * ------------------------------------------------------------------------ **/ -#define cmc_assert_lesser_equals_int8_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int8_t boundary__ = (boundary); \ - int8_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId8 \ - " Actual: %" PRId8 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_int8_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int8_t boundary__ = (boundary); \ + int8_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId8 " Actual: %" PRId8 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_int16_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int16_t boundary__ = (boundary); \ - int16_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId16 \ - " Actual: %" PRId16 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_int16_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int16_t boundary__ = (boundary); \ + int16_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId16 " Actual: %" PRId16 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_int32_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int32_t boundary__ = (boundary); \ - int32_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId32 \ - " Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_int32_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int32_t boundary__ = (boundary); \ + int32_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId32 " Actual: %" PRId32 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_int64_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int64_t boundary__ = (boundary); \ - int64_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId64 \ - " Actual: %" PRId64 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_int64_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int64_t boundary__ = (boundary); \ + int64_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId64 " Actual: %" PRId64 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_uint8_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint8_t boundary__ = (boundary); \ - uint8_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu8 \ - " Actual: %" PRIu8 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_uint8_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint8_t boundary__ = (boundary); \ + uint8_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu8 " Actual: %" PRIu8 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_uint16_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint16_t boundary__ = (boundary); \ - uint16_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu16 \ - " Actual: %" PRIu16 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_uint16_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint16_t boundary__ = (boundary); \ + uint16_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu16 " Actual: %" PRIu16 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_uint32_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint32_t boundary__ = (boundary); \ - uint32_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu32 \ - " Actual: %" PRIu32 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_uint32_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint32_t boundary__ = (boundary); \ + uint32_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu32 " Actual: %" PRIu32 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_uint64_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint64_t boundary__ = (boundary); \ - uint64_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu64 \ - " Actual: %" PRIu64 "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_uint64_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint64_t boundary__ = (boundary); \ + uint64_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu64 " Actual: %" PRIu64 \ + "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_intmax_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - intmax_t boundary__ = (boundary); \ - intmax_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIdMAX \ - " Actual: %" PRIdMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_intmax_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + intmax_t boundary__ = (boundary); \ + intmax_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIdMAX \ + " Actual: %" PRIdMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_uintmax_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uintmax_t boundary__ = (boundary); \ - uintmax_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_uintmax_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uintmax_t boundary__ = (boundary); \ + uintmax_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIuMAX \ + " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_size_t(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - size_t boundary__ = (boundary); \ - size_t actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIuMAX \ - " Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_size_t(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + size_t boundary__ = (boundary); \ + size_t actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIuMAX \ + " Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_float(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - float boundary__ = (boundary); \ - float actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %f Actual: %f\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_float(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + float boundary__ = (boundary); \ + float actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %f Actual: %f\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_lesser_equals_double(boundary, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - double boundary__ = (boundary); \ - double actual__ = (actual); \ - \ - if (actual__ > boundary__) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %lf Actual: %lf\n", \ - __FILE__, __func__, __LINE__, str, boundary__, actual__); \ - } \ - \ +#define cmc_assert_lesser_equals_double(boundary, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + double boundary__ = (boundary); \ + double actual__ = (actual); \ +\ + if (actual__ > boundary__) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %lf Actual: %lf\n", \ + __FILE__, __func__, __LINE__, str, boundary__, actual__); \ + } \ +\ } while (0) /** --------------------------------------------------------------------------- @@ -2206,314 +2041,286 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * ------------------------------------------------------------------------ **/ -#define cmc_assert_in_range_int8_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int8_t lower_bound__ = (lower_bound); \ - int8_t upper_bound__ = (upper_bound); \ - int8_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId8 \ - ", %" PRId8 "] Actual: %" PRId8 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_int8_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int8_t lower_bound__ = (lower_bound); \ + int8_t upper_bound__ = (upper_bound); \ + int8_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId8 ", %" PRId8 \ + "] Actual: %" PRId8 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_int16_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int16_t lower_bound__ = (lower_bound); \ - int16_t upper_bound__ = (upper_bound); \ - int16_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId16 \ - ", %" PRId16 "] Actual: %" PRId16 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_int16_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int16_t lower_bound__ = (lower_bound); \ + int16_t upper_bound__ = (upper_bound); \ + int16_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId16 ", %" PRId16 \ + "] Actual: %" PRId16 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_int32_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int32_t lower_bound__ = (lower_bound); \ - int32_t upper_bound__ = (upper_bound); \ - int32_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId32 \ - ", %" PRId32 "] Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_int32_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int32_t lower_bound__ = (lower_bound); \ + int32_t upper_bound__ = (upper_bound); \ + int32_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId32 ", %" PRId32 \ + "] Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_int64_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int64_t lower_bound__ = (lower_bound); \ - int64_t upper_bound__ = (upper_bound); \ - int64_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId32 \ - ", %" PRId32 "] Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_int64_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int64_t lower_bound__ = (lower_bound); \ + int64_t upper_bound__ = (upper_bound); \ + int64_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId32 ", %" PRId32 \ + "] Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_uint8_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint8_t lower_bound__ = (lower_bound); \ - uint8_t upper_bound__ = (upper_bound); \ - uint8_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu8 \ - ", %" PRIu8 "] Actual: %" PRIu8 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_uint8_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint8_t lower_bound__ = (lower_bound); \ + uint8_t upper_bound__ = (upper_bound); \ + uint8_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu8 ", %" PRIu8 \ + "] Actual: %" PRIu8 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_uint16_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint16_t lower_bound__ = (lower_bound); \ - uint16_t upper_bound__ = (upper_bound); \ - uint16_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu16 \ - ", %" PRIu16 "] Actual: %" PRIu16 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_uint16_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint16_t lower_bound__ = (lower_bound); \ + uint16_t upper_bound__ = (upper_bound); \ + uint16_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu16 ", %" PRIu16 \ + "] Actual: %" PRIu16 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_uint32_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint32_t lower_bound__ = (lower_bound); \ - uint32_t upper_bound__ = (upper_bound); \ - uint32_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu32 \ - ", %" PRIu32 "] Actual: %" PRIu32 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_uint32_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint32_t lower_bound__ = (lower_bound); \ + uint32_t upper_bound__ = (upper_bound); \ + uint32_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu32 ", %" PRIu32 \ + "] Actual: %" PRIu32 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_uint64_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint64_t lower_bound__ = (lower_bound); \ - uint64_t upper_bound__ = (upper_bound); \ - uint64_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu64 \ - ", %" PRIu64 "] Actual: %" PRIu64 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_uint64_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint64_t lower_bound__ = (lower_bound); \ + uint64_t upper_bound__ = (upper_bound); \ + uint64_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu64 ", %" PRIu64 \ + "] Actual: %" PRIu64 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_intmax_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - intmax_t lower_bound__ = (lower_bound); \ - intmax_t upper_bound__ = (upper_bound); \ - intmax_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIdMAX \ - ", %" PRIdMAX "] Actual: %" PRIdMAX "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_intmax_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + intmax_t lower_bound__ = (lower_bound); \ + intmax_t upper_bound__ = (upper_bound); \ + intmax_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIdMAX ", %" PRIdMAX \ + "] Actual: %" PRIdMAX "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_uintmax_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uintmax_t lower_bound__ = (lower_bound); \ - uintmax_t upper_bound__ = (upper_bound); \ - uintmax_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIuMAX \ - ", %" PRIuMAX "] Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_uintmax_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uintmax_t lower_bound__ = (lower_bound); \ + uintmax_t upper_bound__ = (upper_bound); \ + uintmax_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIuMAX ", %" PRIuMAX \ + "] Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_size_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - size_t lower_bound__ = (lower_bound); \ - size_t upper_bound__ = (upper_bound); \ - size_t actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIuMAX \ - ", %" PRIuMAX "] Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_size_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + size_t lower_bound__ = (lower_bound); \ + size_t upper_bound__ = (upper_bound); \ + size_t actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIuMAX ", %" PRIuMAX \ + "] Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_float(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - float lower_bound__ = (lower_bound); \ - float upper_bound__ = (upper_bound); \ - float actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%f, %f] Actual: %f\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_float(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + float lower_bound__ = (lower_bound); \ + float upper_bound__ = (upper_bound); \ + float actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%f, %f] Actual: %f\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_in_range_double(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - double lower_bound__ = (lower_bound); \ - double upper_bound__ = (upper_bound); \ - double actual__ = (actual); \ - \ - if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%lf, %lf] Actual: %lf\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_in_range_double(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + double lower_bound__ = (lower_bound); \ + double upper_bound__ = (upper_bound); \ + double actual__ = (actual); \ +\ + if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%lf, %lf] Actual: %lf\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) /** --------------------------------------------------------------------------- @@ -2522,314 +2329,286 @@ CMC_UNUSED static uintmax_t cmc_assert_failed = 0; * * ------------------------------------------------------------------------ **/ -#define cmc_assert_not_in_range_int8_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int8_t lower_bound__ = (lower_bound); \ - int8_t upper_bound__ = (upper_bound); \ - int8_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId8 \ - ", %" PRId8 "] Actual: %" PRId8 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_int8_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int8_t lower_bound__ = (lower_bound); \ + int8_t upper_bound__ = (upper_bound); \ + int8_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId8 ", %" PRId8 \ + "] Actual: %" PRId8 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_int16_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int16_t lower_bound__ = (lower_bound); \ - int16_t upper_bound__ = (upper_bound); \ - int16_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId16 \ - ", %" PRId16 "] Actual: %" PRId16 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_int16_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int16_t lower_bound__ = (lower_bound); \ + int16_t upper_bound__ = (upper_bound); \ + int16_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId16 ", %" PRId16 \ + "] Actual: %" PRId16 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_int32_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int32_t lower_bound__ = (lower_bound); \ - int32_t upper_bound__ = (upper_bound); \ - int32_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId32 \ - ", %" PRId32 "] Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_int32_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int32_t lower_bound__ = (lower_bound); \ + int32_t upper_bound__ = (upper_bound); \ + int32_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId32 ", %" PRId32 \ + "] Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_int64_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - int64_t lower_bound__ = (lower_bound); \ - int64_t upper_bound__ = (upper_bound); \ - int64_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId32 \ - ", %" PRId32 "] Actual: %" PRId32 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_int64_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + int64_t lower_bound__ = (lower_bound); \ + int64_t upper_bound__ = (upper_bound); \ + int64_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId32 ", %" PRId32 \ + "] Actual: %" PRId32 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_uint8_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint8_t lower_bound__ = (lower_bound); \ - uint8_t upper_bound__ = (upper_bound); \ - uint8_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu8 \ - ", %" PRIu8 "] Actual: %" PRIu8 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_uint8_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint8_t lower_bound__ = (lower_bound); \ + uint8_t upper_bound__ = (upper_bound); \ + uint8_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu8 ", %" PRIu8 \ + "] Actual: %" PRIu8 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_uint16_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint16_t lower_bound__ = (lower_bound); \ - uint16_t upper_bound__ = (upper_bound); \ - uint16_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu16 \ - ", %" PRIu16 "] Actual: %" PRIu16 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_uint16_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint16_t lower_bound__ = (lower_bound); \ + uint16_t upper_bound__ = (upper_bound); \ + uint16_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu16 ", %" PRIu16 \ + "] Actual: %" PRIu16 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_uint32_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint32_t lower_bound__ = (lower_bound); \ - uint32_t upper_bound__ = (upper_bound); \ - uint32_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu32 \ - ", %" PRIu32 "] Actual: %" PRIu32 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_uint32_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint32_t lower_bound__ = (lower_bound); \ + uint32_t upper_bound__ = (upper_bound); \ + uint32_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu32 ", %" PRIu32 \ + "] Actual: %" PRIu32 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_uint64_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uint64_t lower_bound__ = (lower_bound); \ - uint64_t upper_bound__ = (upper_bound); \ - uint64_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu64 \ - ", %" PRIu64 "] Actual: %" PRIu64 "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_uint64_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uint64_t lower_bound__ = (lower_bound); \ + uint64_t upper_bound__ = (upper_bound); \ + uint64_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu64 ", %" PRIu64 \ + "] Actual: %" PRIu64 "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_intmax_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - intmax_t lower_bound__ = (lower_bound); \ - intmax_t upper_bound__ = (upper_bound); \ - intmax_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIdMAX \ - ", %" PRIdMAX "] Actual: %" PRIdMAX "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_intmax_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + intmax_t lower_bound__ = (lower_bound); \ + intmax_t upper_bound__ = (upper_bound); \ + intmax_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIdMAX ", %" PRIdMAX \ + "] Actual: %" PRIdMAX "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_uintmax_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - uintmax_t lower_bound__ = (lower_bound); \ - uintmax_t upper_bound__ = (upper_bound); \ - uintmax_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIuMAX \ - ", %" PRIuMAX "] Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_uintmax_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + uintmax_t lower_bound__ = (lower_bound); \ + uintmax_t upper_bound__ = (upper_bound); \ + uintmax_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIuMAX ", %" PRIuMAX \ + "] Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_size_t(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - size_t lower_bound__ = (lower_bound); \ - size_t upper_bound__ = (upper_bound); \ - size_t actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIuMAX \ - ", %" PRIuMAX "] Actual: %" PRIuMAX "\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_size_t(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + size_t lower_bound__ = (lower_bound); \ + size_t upper_bound__ = (upper_bound); \ + size_t actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, \ + "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIuMAX ", %" PRIuMAX \ + "] Actual: %" PRIuMAX "\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_float(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - float lower_bound__ = (lower_bound); \ - float upper_bound__ = (upper_bound); \ - float actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%f, %f] Actual: %f\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_float(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + float lower_bound__ = (lower_bound); \ + float upper_bound__ = (upper_bound); \ + float actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%f, %f] Actual: %f\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) -#define cmc_assert_not_in_range_double(lower_bound, upper_bound, actual) \ - do \ - { \ - cmc_assert_total++; \ - const char *str = #actual; \ - double lower_bound__ = (lower_bound); \ - double upper_bound__ = (upper_bound); \ - double actual__ = (actual); \ - \ - if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ - { \ - cmc_assert_state = false; \ - cmc_assert_failed++; \ - \ - fprintf( \ - stderr, \ - "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%lf, %lf] Actual: %lf\n", \ - __FILE__, __func__, __LINE__, str, lower_bound__, \ - upper_bound__, actual__); \ - } \ - \ +#define cmc_assert_not_in_range_double(lower_bound, upper_bound, actual) \ + do \ + { \ + cmc_assert_total++; \ + const char *str = #actual; \ + double lower_bound__ = (lower_bound); \ + double upper_bound__ = (upper_bound); \ + double actual__ = (actual); \ +\ + if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \ + { \ + cmc_assert_state = false; \ + cmc_assert_failed++; \ +\ + fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%lf, %lf] Actual: %lf\n", \ + __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \ + } \ +\ } while (0) #endif /* CMC_UTL_ASSERT_H */ diff --git a/src/utl/foreach.h b/src/utl/foreach.h index f84055c..d625380 100644 --- a/src/utl/foreach.h +++ b/src/utl/foreach.h @@ -22,14 +22,12 @@ #include "../cor/core.h" -#define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \ - for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_start)(TARGET); \ - !CMC_(PFX, _iter_at_end)(&ITERNAME); \ +#define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \ + for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_start)(TARGET); !CMC_(PFX, _iter_at_end)(&ITERNAME); \ CMC_(PFX, _iter_next)(&ITERNAME)) -#define CMC_FOREACH_REV(PFX, SNAME, ITERNAME, TARGET) \ - for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_end)(TARGET); \ - !CMC_(PFX, _iter_at_start)(&ITERNAME); \ +#define CMC_FOREACH_REV(PFX, SNAME, ITERNAME, TARGET) \ + for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_end)(TARGET); !CMC_(PFX, _iter_at_start)(&ITERNAME); \ CMC_(PFX, _iter_prev)(&ITERNAME)) #endif /* CMC_UTL_FOREACH_H */ diff --git a/src/utl/log.h b/src/utl/log.h index 6027ee3..284f429 100644 --- a/src/utl/log.h +++ b/src/utl/log.h @@ -66,12 +66,10 @@ #include "../cor/core.h" -static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO", - "WARN", "ERROR", "FATAL" }; +static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" }; #ifdef CMC_LOG_COLOR -static const char *cmc_log_color[] = { "\x1b[94m", "\x1b[36m", "\x1b[32m", - "\x1b[33m", "\x1b[31m", "\x1b[35m" }; +static const char *cmc_log_color[] = { "\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m" }; #endif enum cmc_log_type @@ -95,21 +93,14 @@ static struct } cmc_log_config = { 0, 0, true, true, true, NULL }; -#define cmc_log_trace(fmt, ...) \ - cmc_log(CMC_LOG_TRACE, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) -#define cmc_log_debug(fmt, ...) \ - cmc_log(CMC_LOG_DEBUG, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) -#define cmc_log_info(fmt, ...) \ - cmc_log(CMC_LOG_INFO, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) -#define cmc_log_warn(fmt, ...) \ - cmc_log(CMC_LOG_WARN, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) -#define cmc_log_error(fmt, ...) \ - cmc_log(CMC_LOG_ERROR, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) -#define cmc_log_fatal(fmt, ...) \ - cmc_log(CMC_LOG_FATAL, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) +#define cmc_log_trace(fmt, ...) cmc_log(CMC_LOG_TRACE, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) +#define cmc_log_debug(fmt, ...) cmc_log(CMC_LOG_DEBUG, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) +#define cmc_log_info(fmt, ...) cmc_log(CMC_LOG_INFO, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) +#define cmc_log_warn(fmt, ...) cmc_log(CMC_LOG_WARN, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) +#define cmc_log_error(fmt, ...) cmc_log(CMC_LOG_ERROR, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) +#define cmc_log_fatal(fmt, ...) cmc_log(CMC_LOG_FATAL, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__) -CMC_UNUSED static void cmc_log(enum cmc_log_type log, const char *filename, - const char *funcname, unsigned line, +CMC_UNUSED static void cmc_log(enum cmc_log_type log, const char *filename, const char *funcname, unsigned line, const char *fmt, ...) { if (!cmc_log_config.enabled) @@ -133,11 +124,10 @@ CMC_UNUSED static void cmc_log(enum cmc_log_type log, const char *filename, time[strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", lt)] = '\0'; #ifdef CMC_LOG_COLOR - fprintf(stderr, "%s %s%5s\x1b[0m at\x1b[90m %s:%s:%u\x1b[0m | ", time, - cmc_log_color[i], cmc_log_names[i], filename, funcname, line); -#else - fprintf(stderr, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i], + fprintf(stderr, "%s %s%5s\x1b[0m at\x1b[90m %s:%s:%u\x1b[0m | ", time, cmc_log_color[i], cmc_log_names[i], filename, funcname, line); +#else + fprintf(stderr, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i], filename, funcname, line); #endif va_list args; @@ -168,8 +158,7 @@ skip: char time[32]; time[strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", lt)] = '\0'; - fprintf(cmc_log_config.file, "%s %5s at %s:%s:%u | ", time, - cmc_log_names[i], filename, funcname, line); + fprintf(cmc_log_config.file, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i], filename, funcname, line); va_list file_args; va_start(file_args, fmt); diff --git a/src/utl/test.h b/src/utl/test.h index be7b76f..f604489 100644 --- a/src/utl/test.h +++ b/src/utl/test.h @@ -66,9 +66,7 @@ static inline const char *cmc_test_color(int i) // 3 - Box (gray) // 4 - Name (cyan) // 5 - Total (yellow) - static const char *cmc_test_colors[] = { - "\x1b[0m", "\x1b[31m", "\x1b[32m", "\x1b[90m", "\x1b[36m", "\x1b[33m" - }; + static const char *cmc_test_colors[] = { "\x1b[0m", "\x1b[31m", "\x1b[32m", "\x1b[90m", "\x1b[36m", "\x1b[33m" }; return cmc_test_colors[i]; #else static inline const char *cmc_test_color(int i) @@ -79,9 +77,7 @@ static inline const char *cmc_test_color(int i) } /* Logging function */ -CMC_UNUSED static void cmc_test_log(const char *unit_name, - const char *current_test, bool aborted, - bool passed) +CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_test, bool aborted, bool passed) { if (aborted) { @@ -110,139 +106,132 @@ CMC_UNUSED static void cmc_test_log(const char *unit_name, } } -#define CMC_CREATE_UNIT(UNAME, VERBOSE, BODY) \ - uintmax_t UNAME(void) \ - { \ - const char *unit_name = #UNAME; \ - const char *current_test = NULL; \ - \ - struct cmc_test_info tinfo = { 0 }; \ - struct cmc_timer timer = { 0 }; \ - \ - tinfo.verbose = VERBOSE; \ - tinfo.assert_total = cmc_assert_total; \ - tinfo.assert_failed = cmc_assert_failed; \ - \ - printf("%s", cmc_test_color(3)); \ - printf( \ - " +---------------------------------------------------------------+\n"); \ - printf(" | "); \ - printf("%s", cmc_test_color(0)); \ - printf("Unit "); \ - printf("%s", cmc_test_color(4)); \ - printf("%-56s", unit_name); \ - printf("%s", cmc_test_color(3)); \ - printf( \ - " |\n +---------------------------------------------------------------+"); \ - printf("%s\n", cmc_test_color(0)); \ - \ - /* Tests */ \ - cmc_timer_start(timer); \ - \ - BODY; \ - \ - cmc_timer_stop(timer); \ - \ - unittest_abort: \ - if (tinfo.aborted) \ - { \ - cmc_test_log(unit_name, current_test, true, false); \ - } \ - \ - tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \ - tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \ - \ - printf("%s", cmc_test_color(3)); \ - printf( \ - " +---------------------------------------------------------------+\n | "); \ - printf("%s", cmc_test_color(0)); \ - printf("Summary : "); \ - printf("%s", cmc_test_color(4)); \ - printf("%-52s", unit_name); \ - printf("%s|\n", cmc_test_color(3)); \ - printf( \ - " +---------++----------------+-----------------+-----------------+\n | "); \ - printf("%s", cmc_test_color(0)); \ - printf("Tests "); \ - printf("%s", cmc_test_color(3)); \ - printf("||"); \ - printf("%s", cmc_test_color(5)); \ - printf(" Total %8" PRIuMAX "", tinfo.total); \ - printf("%s", cmc_test_color(3)); \ - printf(" | "); \ - printf("%s", cmc_test_color(2)); \ - printf("Passed %8" PRIuMAX "", tinfo.passed); \ - printf("%s", cmc_test_color(3)); \ - printf(" | "); \ - printf("%s", cmc_test_color(1)); \ - printf("Failed %8" PRIuMAX "", tinfo.failed); \ - printf("%s", cmc_test_color(3)); \ - printf(" |\n | "); \ - printf("%s", cmc_test_color(0)); \ - printf("Asserts "); \ - printf("%s", cmc_test_color(3)); \ - printf("||"); \ - printf("%s", cmc_test_color(5)); \ - printf(" Total %8" PRIuMAX "", tinfo.assert_total); \ - printf("%s", cmc_test_color(3)); \ - printf(" | "); \ - printf("%s", cmc_test_color(2)); \ - printf("Passed %8" PRIuMAX "", \ - tinfo.assert_total - tinfo.assert_failed); \ - printf("%s", cmc_test_color(3)); \ - printf(" | "); \ - printf("%s", cmc_test_color(1)); \ - printf("Failed %8" PRIuMAX "", tinfo.assert_failed); \ - printf("%s", cmc_test_color(3)); \ - printf(" |\n"); \ - printf( \ - " +---------++----------------+-----------------+-----------------+\n | "); \ - printf("%s", cmc_test_color(0)); \ - printf("Total Runtime : %32.0f milliseconds", timer.result); \ - printf(" %s|\n", cmc_test_color(3)); \ - printf( \ - " +---------------------------------------------------------------+\n"); \ - printf("%s", cmc_test_color(0)); \ - printf("\n"); \ - \ - return tinfo.failed; \ +#define CMC_CREATE_UNIT(UNAME, VERBOSE, BODY) \ + uintmax_t UNAME(void) \ + { \ + const char *unit_name = #UNAME; \ + const char *current_test = NULL; \ +\ + struct cmc_test_info tinfo = { 0 }; \ + struct cmc_timer timer = { 0 }; \ +\ + tinfo.verbose = VERBOSE; \ + tinfo.assert_total = cmc_assert_total; \ + tinfo.assert_failed = cmc_assert_failed; \ +\ + printf("%s", cmc_test_color(3)); \ + printf(" +---------------------------------------------------------------+\n"); \ + printf(" | "); \ + printf("%s", cmc_test_color(0)); \ + printf("Unit "); \ + printf("%s", cmc_test_color(4)); \ + printf("%-56s", unit_name); \ + printf("%s", cmc_test_color(3)); \ + printf(" |\n +---------------------------------------------------------------+"); \ + printf("%s\n", cmc_test_color(0)); \ +\ + /* Tests */ \ + cmc_timer_start(timer); \ +\ + BODY; \ +\ + cmc_timer_stop(timer); \ +\ + unittest_abort: \ + if (tinfo.aborted) \ + { \ + cmc_test_log(unit_name, current_test, true, false); \ + } \ +\ + tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \ + tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \ +\ + printf("%s", cmc_test_color(3)); \ + printf(" +---------------------------------------------------------------+\n | "); \ + printf("%s", cmc_test_color(0)); \ + printf("Summary : "); \ + printf("%s", cmc_test_color(4)); \ + printf("%-52s", unit_name); \ + printf("%s|\n", cmc_test_color(3)); \ + printf(" +---------++----------------+-----------------+-----------------+\n | "); \ + printf("%s", cmc_test_color(0)); \ + printf("Tests "); \ + printf("%s", cmc_test_color(3)); \ + printf("||"); \ + printf("%s", cmc_test_color(5)); \ + printf(" Total %8" PRIuMAX "", tinfo.total); \ + printf("%s", cmc_test_color(3)); \ + printf(" | "); \ + printf("%s", cmc_test_color(2)); \ + printf("Passed %8" PRIuMAX "", tinfo.passed); \ + printf("%s", cmc_test_color(3)); \ + printf(" | "); \ + printf("%s", cmc_test_color(1)); \ + printf("Failed %8" PRIuMAX "", tinfo.failed); \ + printf("%s", cmc_test_color(3)); \ + printf(" |\n | "); \ + printf("%s", cmc_test_color(0)); \ + printf("Asserts "); \ + printf("%s", cmc_test_color(3)); \ + printf("||"); \ + printf("%s", cmc_test_color(5)); \ + printf(" Total %8" PRIuMAX "", tinfo.assert_total); \ + printf("%s", cmc_test_color(3)); \ + printf(" | "); \ + printf("%s", cmc_test_color(2)); \ + printf("Passed %8" PRIuMAX "", tinfo.assert_total - tinfo.assert_failed); \ + printf("%s", cmc_test_color(3)); \ + printf(" | "); \ + printf("%s", cmc_test_color(1)); \ + printf("Failed %8" PRIuMAX "", tinfo.assert_failed); \ + printf("%s", cmc_test_color(3)); \ + printf(" |\n"); \ + printf(" +---------++----------------+-----------------+-----------------+\n | "); \ + printf("%s", cmc_test_color(0)); \ + printf("Total Runtime : %32.0f milliseconds", timer.result); \ + printf(" %s|\n", cmc_test_color(3)); \ + printf(" +---------------------------------------------------------------+\n"); \ + printf("%s", cmc_test_color(0)); \ + printf("\n"); \ +\ + return tinfo.failed; \ } -#define CMC_CREATE_TEST(TNAME, BODY) \ - do \ - { \ - current_test = #TNAME; \ - \ - tinfo.total += 1; \ - \ - /* Provided by assert.h */ \ - cmc_assert_state = true; \ - \ - BODY; \ - \ - if (tinfo.verbose) \ - { \ - if (!cmc_assert_state) \ - { \ - tinfo.failed += 1; \ +#define CMC_CREATE_TEST(TNAME, BODY) \ + do \ + { \ + current_test = #TNAME; \ +\ + tinfo.total += 1; \ +\ + /* Provided by assert.h */ \ + cmc_assert_state = true; \ +\ + BODY; \ +\ + if (tinfo.verbose) \ + { \ + if (!cmc_assert_state) \ + { \ + tinfo.failed += 1; \ cmc_test_log(unit_name, current_test, false, false); \ - } \ - else \ - { \ - tinfo.passed += 1; \ - cmc_test_log(unit_name, current_test, false, true); \ - } \ - } \ - \ + } \ + else \ + { \ + tinfo.passed += 1; \ + cmc_test_log(unit_name, current_test, false, true); \ + } \ + } \ +\ } while (0) -#define CMC_TEST_ABORT() \ - do \ - { \ +#define CMC_TEST_ABORT() \ + do \ + { \ tinfo.aborted = true; \ - tinfo.total -= 1; \ - goto unittest_abort; \ - \ + tinfo.total -= 1; \ + goto unittest_abort; \ +\ } while (0) #endif /* CMC_UTL_TEST_H */ diff --git a/src/utl/thread.h b/src/utl/thread.h index 6848e1e..22c34e5 100644 --- a/src/utl/thread.h +++ b/src/utl/thread.h @@ -88,8 +88,7 @@ static void *cmc_thread_wrapper(void *arg) * \param args The arguments passed to the proc function. * \return True or false if the thread creation was successfull. */ -static inline bool cmc_thrd_create(struct cmc_thread *thr, cmc_thread_proc proc, - void *args) +static inline bool cmc_thrd_create(struct cmc_thread *thr, cmc_thread_proc proc, void *args) { #if defined(CMC_THREAD_WINDOWS) thr->args = args; diff --git a/src/utl/timer.h b/src/utl/timer.h index deefdd5..79857c3 100644 --- a/src/utl/timer.h +++ b/src/utl/timer.h @@ -24,20 +24,19 @@ struct cmc_timer double result; /* The result is given in milliseconds */ }; -#define cmc_timer_start(timer) \ - do \ - { \ +#define cmc_timer_start(timer) \ + do \ + { \ struct cmc_timer *t__ = &(timer); \ - t__->start = clock(); \ + t__->start = clock(); \ } while (0) -#define cmc_timer_stop(timer) \ - do \ - { \ - struct cmc_timer *t__ = &(timer); \ - t__->stop = clock(); \ - t__->result = \ - (double)(t__->stop - t__->start) * 1000.0 / CLOCKS_PER_SEC; \ +#define cmc_timer_stop(timer) \ + do \ + { \ + struct cmc_timer *t__ = &(timer); \ + t__->stop = clock(); \ + t__->result = (double)(t__->stop - t__->start) * 1000.0 / CLOCKS_PER_SEC; \ } while (0) #endif /* CMC_UTL_TIMER_H */ diff --git a/tests/main/main.c b/tests/main/main.c index 076452d..0f00641 100644 --- a/tests/main/main.c +++ b/tests/main/main.c @@ -20,15 +20,12 @@ #include "unt/foreach.c" #define cmc_run(unit, unit_fails, test_fails) \ - do \ - { \ - uintmax_t f = unit(); \ - \ - if (f != 0) \ - unit_fails += 1; \ - \ - test_fails += f; \ - \ + do \ + { \ + uintmax_t f = unit(); \ + if (f != 0) \ + unit_fails += 1; \ + test_fails += f; \ } while (0) int main(void) @@ -86,19 +83,14 @@ int main(void) cmc_timer_stop(timer); - printf( - " +---------------------------------------------------------------+\n"); - printf( - " | SUMMARY |\n"); - printf( - " +---------------------------------------------------------------+\n"); + printf(" +---------------------------------------------------------------+\n"); + printf(" | SUMMARY |\n"); + printf(" +---------------------------------------------------------------+\n"); printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units); printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests); - printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", - cmc_assert_failed); + printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", cmc_assert_failed); printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result); - printf( - " +---------------------------------------------------------------+\n"); + printf(" +---------------------------------------------------------------+\n"); return tests; } diff --git a/tests/main/src/bitset.c b/tests/main/src/bitset.c index 5975085..93f3f3c 100644 --- a/tests/main/src/bitset.c +++ b/tests/main/src/bitset.c @@ -19,15 +19,12 @@ struct bitset_iter _Bool end; }; struct bitset *bs_new(size_t n_bits); -struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); struct bitset bs_init(size_t n_bits); -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void bs_free(struct bitset *_bitset_); void bs_release(struct bitset _bitset_); -void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool bs_set(struct bitset *_bitset_, size_t bit_index); _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to); _Bool bs_clear(struct bitset *_bitset_, size_t bit_index); @@ -35,8 +32,7 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to); _Bool bs_flip(struct bitset *_bitset_, size_t bit_index); _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to); _Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state); -_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, - _Bool state); +_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state); _Bool bs_set_all(struct bitset *_bitset_); _Bool bs_clear_all(struct bitset *_bitset_); _Bool bs_flip_all(struct bitset *_bitset_); @@ -47,9 +43,7 @@ static inline size_t bs_bit_to_index(size_t idx) static const size_t shift = ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 ? 6 - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 - ? 5 - : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; + : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; return idx >> shift; } _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize); @@ -57,8 +51,7 @@ struct bitset *bs_new(size_t n_bits) { return bs_new_custom(n_bits, ((void *)0), ((void *)0)); } -struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (n_bits < 1) return ((void *)0); @@ -84,8 +77,7 @@ struct bitset bs_init(size_t n_bits) { return bs_init_custom(n_bits, ((void *)0), ((void *)0)); } -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { struct bitset _bitset_ = { 0 }; if (n_bits < 1) @@ -111,8 +103,7 @@ void bs_release(struct bitset _bitset_) { free(_bitset_.buffer); } -void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _bitset_->alloc = &cmc_alloc_node_default; @@ -317,8 +308,7 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) size_t words = bs_bit_to_index(n_bits - 1) + 1; if (!do_resize && words <= _bitset_->capacity) return 1; - cmc_bitset_word *new_buffer = - realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); + cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); if (!new_buffer) { _bitset_->flag = CMC_FLAG_ALLOC; @@ -326,8 +316,7 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) } _bitset_->buffer = new_buffer; if (_bitset_->capacity < words) - memset(_bitset_->buffer + _bitset_->capacity, 0, - (words - _bitset_->capacity) * sizeof(cmc_bitset_word)); + memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word)); _bitset_->capacity = words; if (_bitset_->callbacks && _bitset_->callbacks->resize) _bitset_->callbacks->resize(); diff --git a/tests/main/src/deque.c b/tests/main/src/deque.c index ef319b7..8d83464 100644 --- a/tests/main/src/deque.c +++ b/tests/main/src/deque.c @@ -33,14 +33,12 @@ struct deque_iter _Bool end; }; struct deque *d_new(size_t capacity, struct deque_fval *f_val); -struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, - struct cmc_alloc_node *alloc, +struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void d_clear(struct deque *_deque_); void d_free(struct deque *_deque_); void d_release(struct deque _deque_); -void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool d_push_front(struct deque *_deque_, size_t value); _Bool d_push_back(struct deque *_deque_, size_t value); _Bool d_pop_front(struct deque *_deque_); @@ -76,8 +74,7 @@ struct deque *d_new(size_t capacity, struct deque_fval *f_val) { return d_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } -struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, - struct cmc_alloc_node *alloc, +struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity < 1) @@ -146,8 +143,7 @@ void d_release(struct deque _deque_) } _deque_.alloc->free(_deque_.buffer); } -void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _deque_->alloc = &cmc_alloc_node_default; @@ -163,8 +159,7 @@ _Bool d_push_front(struct deque *_deque_, size_t value) if (!d_resize(_deque_, _deque_->capacity * 2)) return 0; } - _deque_->front = - (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; + _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; _deque_->buffer[_deque_->front] = value; _deque_->count++; _deque_->flag = CMC_FLAG_OK; @@ -180,8 +175,7 @@ _Bool d_push_back(struct deque *_deque_, size_t value) return 0; } _deque_->buffer[_deque_->back] = value; - _deque_->back = - (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; + _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; _deque_->count++; _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->create) @@ -196,8 +190,7 @@ _Bool d_pop_front(struct deque *_deque_) return 0; } _deque_->buffer[_deque_->front] = (size_t){ 0 }; - _deque_->front = - (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; + _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; _deque_->count--; _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->delete) @@ -211,8 +204,7 @@ _Bool d_pop_back(struct deque *_deque_) _deque_->flag = CMC_FLAG_EMPTY; return 0; } - _deque_->back = - (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; + _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; _deque_->buffer[_deque_->back] = (size_t){ 0 }; _deque_->count--; _deque_->flag = CMC_FLAG_OK; @@ -242,8 +234,7 @@ size_t d_back(struct deque *_deque_) _deque_->flag = CMC_FLAG_OK; if (_deque_->callbacks && _deque_->callbacks->read) _deque_->callbacks->read(); - return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 - : _deque_->back - 1]; + return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; } _Bool d_contains(struct deque *_deque_, size_t value) { @@ -315,8 +306,7 @@ success: } struct deque *d_copy_of(struct deque *_deque_) { - struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, - _deque_->alloc, _deque_->callbacks); + struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, _deque_->callbacks); if (!result) { _deque_->flag = CMC_FLAG_ERROR; @@ -351,8 +341,7 @@ _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_) if (_deque1_->count != _deque2_->count) return 0; size_t i, j, k; - for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; - k++) + for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; k++) { if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) return 0; @@ -451,8 +440,7 @@ _Bool d_iter_prev(struct deque_iter *iter) return 0; } iter->end = d_empty(iter->target); - iter->cursor = - (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; iter->index--; return 1; } diff --git a/tests/main/src/hashbidimap.c b/tests/main/src/hashbidimap.c index f9cb231..32029fd 100644 --- a/tests/main/src/hashbidimap.c +++ b/tests/main/src/hashbidimap.c @@ -52,25 +52,19 @@ struct hashbidimap_iter _Bool start; _Bool end; }; -struct hashbidimap *hbm_new(size_t capacity, double load, - struct hashbidimap_fkey *f_key, +struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, struct hashbidimap_fval *f_val); -struct hashbidimap *hbm_new_custom(size_t capacity, double load, - struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val, - struct cmc_alloc_node *alloc, +struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void hbm_clear(struct hashbidimap *_map_); void hbm_free(struct hashbidimap *_map_); -void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value); _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key); _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val); -_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, - size_t *out_val); -_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, - size_t *out_val); +_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val); +_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val); size_t hbm_get_key(struct hashbidimap *_map_, size_t val); size_t hbm_get_val(struct hashbidimap *_map_, size_t key); _Bool hbm_contains_key(struct hashbidimap *_map_, size_t key); @@ -101,23 +95,15 @@ _Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); size_t hbm_iter_key(struct hashbidimap_iter *iter); size_t hbm_iter_value(struct hashbidimap_iter *iter); size_t hbm_iter_index(struct hashbidimap_iter *iter); -static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, - size_t key, size_t value); -static struct hashbidimap_entry ** -hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key); -static struct hashbidimap_entry ** -hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val); -static struct hashbidimap_entry ** -hbm_impl_add_entry_to_key(struct hashbidimap *_map_, - struct hashbidimap_entry *entry); -static struct hashbidimap_entry ** -hbm_impl_add_entry_to_val(struct hashbidimap *_map_, - struct hashbidimap_entry *entry); +static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value); +static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key); +static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val); +static struct hashbidimap_entry **hbm_impl_add_entry_to_key(struct hashbidimap *_map_, struct hashbidimap_entry *entry); +static struct hashbidimap_entry **hbm_impl_add_entry_to_val(struct hashbidimap *_map_, struct hashbidimap_entry *entry); static size_t hbm_impl_calculate_size(size_t required); static struct hashbidimap_iter hbm_impl_it_start(struct hashbidimap *_map_); static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_); -struct hashbidimap *hbm_new(size_t capacity, double load, - struct hashbidimap_fkey *f_key, +struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, struct hashbidimap_fval *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; @@ -131,8 +117,7 @@ struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); if (!_map_) return ((void *)0); - _map_->buffer = - alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_->buffer); @@ -151,10 +136,8 @@ struct hashbidimap *hbm_new(size_t capacity, double load, _map_->it_end = hbm_impl_it_end; return _map_; } -struct hashbidimap *hbm_new_custom(size_t capacity, double load, - struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val, - struct cmc_alloc_node *alloc, +struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity == 0 || load <= 0 || load >= 1) @@ -169,8 +152,7 @@ struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); if (!_map_) return ((void *)0); - _map_->buffer = - alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_->buffer); @@ -215,8 +197,7 @@ void hbm_free(struct hashbidimap *_map_) _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } -void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _map_->alloc = &cmc_alloc_node_default; @@ -232,17 +213,14 @@ _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) if (!hbm_resize(_map_, _map_->capacity + 1)) return 0; } - if (hbm_impl_get_entry_by_key(_map_, key) != ((void *)0) || - hbm_impl_get_entry_by_val(_map_, value) != ((void *)0)) + if (hbm_impl_get_entry_by_key(_map_, key) != ((void *)0) || hbm_impl_get_entry_by_val(_map_, value) != ((void *)0)) { _map_->flag = CMC_FLAG_DUPLICATE; return 0; } struct hashbidimap_entry *entry = hbm_impl_new_entry(_map_, key, value); - struct hashbidimap_entry **key_entry = - hbm_impl_add_entry_to_key(_map_, entry); - struct hashbidimap_entry **val_entry = - hbm_impl_add_entry_to_val(_map_, entry); + struct hashbidimap_entry **key_entry = hbm_impl_add_entry_to_key(_map_, entry); + struct hashbidimap_entry **val_entry = hbm_impl_add_entry_to_val(_map_, entry); if (!key_entry || !val_entry) { if (key_entry) @@ -347,8 +325,7 @@ success: _map_->callbacks->update(); return 1; } -_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, - size_t *out_val) +_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val) { if (hbm_empty(_map_)) { @@ -381,8 +358,7 @@ _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, _map_->callbacks->delete (); return 1; } -_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, - size_t *out_val) +_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val) { if (hbm_empty(_map_)) { @@ -500,8 +476,7 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) return 0; } struct hashbidimap *_new_map_ = - hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); + hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; @@ -512,10 +487,8 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) struct hashbidimap_entry *scan = _map_->buffer[i][0]; if (scan && scan != ((void *)1)) { - struct hashbidimap_entry **e1 = - hbm_impl_add_entry_to_key(_new_map_, scan); - struct hashbidimap_entry **e2 = - hbm_impl_add_entry_to_val(_new_map_, scan); + struct hashbidimap_entry **e1 = hbm_impl_add_entry_to_key(_new_map_, scan); + struct hashbidimap_entry **e2 = hbm_impl_add_entry_to_val(_new_map_, scan); if (!e1 || !e2) { _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; @@ -549,9 +522,8 @@ success: } struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) { - struct hashbidimap *result = - hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, - _map_->f_val, _map_->alloc, _map_->callbacks); + struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, + _map_->alloc, _map_->callbacks); if (!result) { _map_->flag = CMC_FLAG_ERROR; @@ -572,8 +544,7 @@ struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) tmp_val = _map_->f_val->cpy(scan->value); else tmp_val = scan->value; - struct hashbidimap_entry *entry = - hbm_impl_new_entry(result, tmp_key, tmp_val); + struct hashbidimap_entry *entry = hbm_impl_new_entry(result, tmp_key, tmp_val); hbm_impl_add_entry_to_key(result, entry); hbm_impl_add_entry_to_val(result, entry); result->count++; @@ -605,8 +576,7 @@ _Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_) struct hashbidimap_entry *scan = _mapA_->buffer[i][0]; if (scan && scan != ((void *)1)) { - struct hashbidimap_entry **entry_B = - hbm_impl_get_entry_by_key(_mapB_, scan->key); + struct hashbidimap_entry **entry_B = hbm_impl_get_entry_by_key(_mapB_, scan->key); if (!entry_B) return 0; if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) @@ -615,36 +585,9 @@ _Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_) } return 1; } -struct cmc_string hbm_to_string(struct hashbidimap *_map_) -{ - struct cmc_string str; - struct hashbidimap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashbidimap, - "CMC_PARAM_SNAME((hbm, hashbidimap, , size_t, size_t))", - "CMC_PARAM_K((hbm, hashbidimap, , size_t, size_t))", - "CMC_PARAM_V((hbm, hashbidimap, , size_t, size_t))", m_, - m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, m_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr) -{ - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashbidimap_entry *target = _map_->buffer[i][0]; - if (target && target != ((void *)1)) - { - if (!_map_->f_key->str(fptr, target->key) || - !_map_->f_val->str(fptr, target->value)) - return 0; - } - } - return 1; -} struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target) { - struct hashbidimap_iter *iter = - target->alloc->malloc(sizeof(struct hashbidimap_iter)); + struct hashbidimap_iter *iter = target->alloc->malloc(sizeof(struct hashbidimap_iter)); if (!iter) return ((void *)0); hbm_iter_init(iter, target); @@ -815,11 +758,9 @@ size_t hbm_iter_index(struct hashbidimap_iter *iter) { return iter->index; } -static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, - size_t key, size_t value) +static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value) { - struct hashbidimap_entry *entry = - _map_->alloc->malloc(sizeof(struct hashbidimap_entry)); + struct hashbidimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashbidimap_entry)); if (!entry) return ((void *)0); entry->key = key; @@ -830,8 +771,7 @@ static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, entry->ref[1] = ((void *)0); return entry; } -static struct hashbidimap_entry ** -hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key) +static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key) { size_t hash = _map_->f_key->hash(key); size_t pos = hash % _map_->capacity; @@ -845,8 +785,7 @@ hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key) } return ((void *)0); } -static struct hashbidimap_entry ** -hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val) +static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val) { size_t hash = _map_->f_val->hash(val); size_t pos = hash % _map_->capacity; @@ -860,16 +799,13 @@ hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val) } return ((void *)0); } -static struct hashbidimap_entry ** -hbm_impl_add_entry_to_key(struct hashbidimap *_map_, - struct hashbidimap_entry *entry) +static struct hashbidimap_entry **hbm_impl_add_entry_to_key(struct hashbidimap *_map_, struct hashbidimap_entry *entry) { struct hashbidimap_entry **to_return = ((void *)0); size_t hash = _map_->f_key->hash(entry->key); size_t original_pos = hash % _map_->capacity; size_t pos = original_pos; - struct hashbidimap_entry **scan = - &(_map_->buffer[hash % _map_->capacity][0]); + struct hashbidimap_entry **scan = &(_map_->buffer[hash % _map_->capacity][0]); if (*scan == ((void *)0)) { *scan = entry; @@ -907,16 +843,13 @@ hbm_impl_add_entry_to_key(struct hashbidimap *_map_, } return ((void *)0); } -static struct hashbidimap_entry ** -hbm_impl_add_entry_to_val(struct hashbidimap *_map_, - struct hashbidimap_entry *entry) +static struct hashbidimap_entry **hbm_impl_add_entry_to_val(struct hashbidimap *_map_, struct hashbidimap_entry *entry) { struct hashbidimap_entry **to_return = ((void *)0); size_t hash = _map_->f_val->hash(entry->value); size_t original_pos = hash % _map_->capacity; size_t pos = original_pos; - struct hashbidimap_entry **scan = - &(_map_->buffer[hash % _map_->capacity][1]); + struct hashbidimap_entry **scan = &(_map_->buffer[hash % _map_->capacity][1]); if (*scan == ((void *)0)) { *scan = entry; @@ -956,8 +889,7 @@ hbm_impl_add_entry_to_val(struct hashbidimap *_map_, } static size_t hbm_impl_calculate_size(size_t required) { - const size_t count = - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; diff --git a/tests/main/src/hashmap.c b/tests/main/src/hashmap.c index 63ccc60..d9b1f95 100644 --- a/tests/main/src/hashmap.c +++ b/tests/main/src/hashmap.c @@ -50,21 +50,15 @@ struct hashmap_iter _Bool start; _Bool end; }; -struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, - struct hashmap_fval *f_val); -struct hashmap *hm_new_custom(size_t capacity, double load, - struct hashmap_fkey *f_key, - struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); +struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void hm_clear(struct hashmap *_map_); void hm_free(struct hashmap *_map_); void hm_release(struct hashmap _map_); -void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); -_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, - size_t *old_value); +_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value); _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value); _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value); _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value); @@ -97,20 +91,14 @@ size_t hm_iter_key(struct hashmap_iter *iter); size_t hm_iter_value(struct hashmap_iter *iter); size_t *hm_iter_rvalue(struct hashmap_iter *iter); size_t hm_iter_index(struct hashmap_iter *iter); -static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, - size_t key); +static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key); static size_t hm_impl_calculate_size(size_t required); -struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, - struct hashmap_fval *f_val) +struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) { - return hm_new_custom(capacity, load, f_key, f_val, ((void *)0), - ((void *)0)); + return hm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } -struct hashmap *hm_new_custom(size_t capacity, double load, - struct hashmap_fkey *f_key, - struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); @@ -197,8 +185,7 @@ void hm_release(struct hashmap _map_) } _map_.alloc->free(_map_.buffer); } -void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _map_->alloc = &cmc_alloc_node_default; @@ -236,8 +223,7 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) { pos++; target = &(_map_->buffer[pos % _map_->capacity]); - if (target->state == CMC_ES_EMPTY || - target->state == CMC_ES_DELETED) + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->key = key; target->value = value; @@ -265,8 +251,7 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) _map_->callbacks->create(); return 1; } -_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, - size_t *old_value) +_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value) { if (hm_empty(_map_)) { @@ -457,8 +442,7 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) return 0; } struct hashmap *_new_map_ = - hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); + hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; @@ -493,9 +477,8 @@ success: } struct hashmap *hm_copy_of(struct hashmap *_map_) { - struct hashmap *result = - hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, - _map_->f_val, _map_->alloc, _map_->callbacks); + struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, + _map_->alloc, _map_->callbacks); if (!result) { _map_->flag = CMC_FLAG_ERROR; @@ -528,8 +511,7 @@ struct hashmap *hm_copy_of(struct hashmap *_map_) } } else - memcpy(result->buffer, _map_->buffer, - sizeof(struct hashmap_entry) * _map_->capacity); + memcpy(result->buffer, _map_->buffer, sizeof(struct hashmap_entry) * _map_->capacity); result->count = _map_->count; _map_->flag = CMC_FLAG_OK; return result; @@ -543,8 +525,7 @@ _Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_) struct hashmap_iter iter = hm_iter_start(_map1_); for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) { - struct hashmap_entry *entry = - hm_impl_get_entry(_map2_, hm_iter_key(&iter)); + struct hashmap_entry *entry = hm_impl_get_entry(_map2_, hm_iter_key(&iter)); if (entry == ((void *)0)) return 0; if (_map1_->f_val->cmp(entry->value, hm_iter_value(&iter)) != 0) @@ -753,8 +734,7 @@ size_t hm_iter_index(struct hashmap_iter *iter) { return iter->index; } -static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, - size_t key) +static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key) { size_t hash = _map_->f_key->hash(key); size_t pos = hash % _map_->capacity; @@ -770,8 +750,7 @@ static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, } static size_t hm_impl_calculate_size(size_t required) { - const size_t count = - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; diff --git a/tests/main/src/hashmultimap.c b/tests/main/src/hashmultimap.c index dd64884..981f107 100644 --- a/tests/main/src/hashmultimap.c +++ b/tests/main/src/hashmultimap.c @@ -51,26 +51,19 @@ struct hashmultimap_iter _Bool start; _Bool end; }; -struct hashmultimap *hmm_new(size_t capacity, double load, - struct hashmultimap_fkey *f_key, +struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, struct hashmultimap_fval *f_val); -struct hashmultimap *hmm_new_custom(size_t capacity, double load, - struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val, - struct cmc_alloc_node *alloc, +struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, + struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void hmm_clear(struct hashmultimap *_map_); void hmm_free(struct hashmultimap *_map_); -void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value); -_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, - size_t *old_value); -size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, - size_t **old_values); +_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value); +size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values); _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value); -size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, - size_t **out_values); +size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values); _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value); _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value); size_t hmm_get(struct hashmultimap *_map_, size_t key); @@ -103,14 +96,11 @@ size_t hmm_iter_key(struct hashmultimap_iter *iter); size_t hmm_iter_value(struct hashmultimap_iter *iter); size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter); size_t hmm_iter_index(struct hashmultimap_iter *iter); -struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, - size_t key, size_t value); -struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, - size_t key); +struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value); +struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key); size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key); size_t hmm_impl_calculate_size(size_t required); -struct hashmultimap *hmm_new(size_t capacity, double load, - struct hashmultimap_fkey *f_key, +struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, struct hashmultimap_fval *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; @@ -124,8 +114,7 @@ struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); if (!_map_) return ((void *)0); - _map_->buffer = - alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_); @@ -141,10 +130,8 @@ struct hashmultimap *hmm_new(size_t capacity, double load, _map_->callbacks = ((void *)0); return _map_; } -struct hashmultimap *hmm_new_custom(size_t capacity, double load, - struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val, - struct cmc_alloc_node *alloc, +struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, + struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity == 0 || load <= 0) @@ -159,8 +146,7 @@ struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); if (!_map_) return ((void *)0); - _map_->buffer = - alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_); @@ -192,8 +178,7 @@ void hmm_clear(struct hashmultimap *_map_) scan = next; } } - memset(_map_->buffer, 0, - sizeof(struct hashmultimap_entry *[2]) * _map_->capacity); + memset(_map_->buffer, 0, sizeof(struct hashmultimap_entry *[2]) * _map_->capacity); _map_->count = 0; _map_->flag = CMC_FLAG_OK; } @@ -232,8 +217,7 @@ void hmm_free(struct hashmultimap *_map_) _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } -void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _map_->alloc = &cmc_alloc_node_default; @@ -269,8 +253,7 @@ _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) _map_->callbacks->create(); return 1; } -_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, - size_t *old_value) +_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value) { if (hmm_empty(_map_)) { @@ -291,8 +274,7 @@ _Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, _map_->callbacks->update(); return 1; } -size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, - size_t **old_values) +size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values) { if (hmm_empty(_map_)) { @@ -346,10 +328,8 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) return 0; } size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry **head = - &(_map_->buffer[hash % _map_->capacity][0]); - struct hashmultimap_entry **tail = - &(_map_->buffer[hash % _map_->capacity][1]); + struct hashmultimap_entry **head = &(_map_->buffer[hash % _map_->capacity][0]); + struct hashmultimap_entry **tail = &(_map_->buffer[hash % _map_->capacity][1]); if (*head == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; @@ -407,8 +387,7 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) _map_->callbacks->delete (); return 1; } -size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, - size_t **out_values) +size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values) { if (hmm_empty(_map_)) { @@ -416,10 +395,8 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, return 0; } size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry **head = - &(_map_->buffer[hash % _map_->capacity][0]); - struct hashmultimap_entry **tail = - &(_map_->buffer[hash % _map_->capacity][1]); + struct hashmultimap_entry **head = &(_map_->buffer[hash % _map_->capacity][0]); + struct hashmultimap_entry **tail = &(_map_->buffer[hash % _map_->capacity][1]); if (*head == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; @@ -643,8 +620,7 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) return 0; } struct hashmultimap *_new_map_ = - hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); + hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; @@ -679,9 +655,8 @@ success: } struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) { - struct hashmultimap *result = - hmm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, - _map_->f_val, _map_->alloc, ((void *)0)); + struct hashmultimap *result = hmm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, + _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; @@ -935,11 +910,9 @@ size_t hmm_iter_index(struct hashmultimap_iter *iter) { return iter->index; } -struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, - size_t key, size_t value) +struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value) { - struct hashmultimap_entry *entry = - _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); + struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); if (!entry) return ((void *)0); entry->key = key; @@ -948,8 +921,7 @@ struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, entry->prev = ((void *)0); return entry; } -struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, - size_t key) +struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key) { size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; @@ -978,8 +950,7 @@ size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) } size_t hmm_impl_calculate_size(size_t required) { - const size_t count = - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; diff --git a/tests/main/src/hashmultiset.c b/tests/main/src/hashmultiset.c index 579799a..b87f565 100644 --- a/tests/main/src/hashmultiset.c +++ b/tests/main/src/hashmultiset.c @@ -41,16 +41,12 @@ struct hashmultiset_iter _Bool start; _Bool end; }; -struct hashmultiset *hms_new(size_t capacity, double load, - struct hashmultiset_fval *f_val); -struct hashmultiset *hms_new_custom(size_t capacity, double load, - struct hashmultiset_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val); +struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void hms_clear(struct hashmultiset *_set_); void hms_free(struct hashmultiset *_set_); -void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool hms_insert(struct hashmultiset *_set_, size_t value); _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count); _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity); @@ -72,24 +68,16 @@ struct hashmultiset *hms_copy_of(struct hashmultiset *_set_); _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_); struct cmc_string hms_to_string(struct hashmultiset *_set_); _Bool hms_print(struct hashmultiset *_set_, FILE *fptr); -struct hashmultiset *hms_union(struct hashmultiset *_set1_, - struct hashmultiset *_set2_); -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, - struct hashmultiset *_set2_); -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, - struct hashmultiset *_set2_); -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, - struct hashmultiset *_set2_); -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, - struct hashmultiset *_set2_); +struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); _Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); _Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, - struct hashmultiset *_set2_); -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, - struct hashmultiset *_set2_); -_Bool hms_is_disjointset(struct hashmultiset *_set1_, - struct hashmultiset *_set2_); +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); struct hashmultiset_iter hms_iter_start(struct hashmultiset *target); struct hashmultiset_iter hms_iter_end(struct hashmultiset *target); _Bool hms_iter_at_start(struct hashmultiset_iter *iter); @@ -104,16 +92,11 @@ _Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index); size_t hms_iter_value(struct hashmultiset_iter *iter); size_t hms_iter_multiplicity(struct hashmultiset_iter *iter); size_t hms_iter_index(struct hashmultiset_iter *iter); -static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, - size_t value); -static struct hashmultiset_entry * -hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, - _Bool *new_node); -static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, - size_t value); +static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value); +static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node); +static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value); static size_t hms_impl_calculate_size(size_t required); -struct hashmultiset *hms_new(size_t capacity, double load, - struct hashmultiset_fval *f_val) +struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity == 0 || load <= 0 || load >= 1) @@ -126,8 +109,7 @@ struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); if (!_set_) return ((void *)0); - _set_->buffer = - alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); + _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); if (!_set_->buffer) { alloc->free(_set_); @@ -143,10 +125,8 @@ struct hashmultiset *hms_new(size_t capacity, double load, _set_->callbacks = ((void *)0); return _set_; } -struct hashmultiset *hms_new_custom(size_t capacity, double load, - struct hashmultiset_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); @@ -160,8 +140,7 @@ struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); if (!_set_) return ((void *)0); - _set_->buffer = - alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); + _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); if (!_set_->buffer) { alloc->free(_set_); @@ -190,8 +169,7 @@ void hms_clear(struct hashmultiset *_set_) } } } - memset(_set_->buffer, 0, - sizeof(struct hashmultiset_entry) * _set_->capacity); + memset(_set_->buffer, 0, sizeof(struct hashmultiset_entry) * _set_->capacity); _set_->count = 0; _set_->flag = CMC_FLAG_OK; } @@ -211,8 +189,7 @@ void hms_free(struct hashmultiset *_set_) _set_->alloc->free(_set_->buffer); _set_->alloc->free(_set_); } -void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _set_->alloc = &cmc_alloc_node_default; @@ -224,8 +201,7 @@ void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, _Bool hms_insert(struct hashmultiset *_set_, size_t value) { _Bool new_node; - struct hashmultiset_entry *entry = - hms_impl_insert_and_return(_set_, value, &new_node); + struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node); if (!entry) { _set_->flag = CMC_FLAG_ERROR; @@ -244,8 +220,7 @@ _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count) if (count == 0) goto success; _Bool new_node; - struct hashmultiset_entry *entry = - hms_impl_insert_and_return(_set_, value, &new_node); + struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node); if (!entry) { _set_->flag = CMC_FLAG_ERROR; @@ -278,14 +253,12 @@ _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) goto success; } _Bool new_node; - struct hashmultiset_entry *entry = - hms_impl_insert_and_return(_set_, value, &new_node); + struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node); if (!entry) return 0; if (new_node) _set_->cardinality++; - _set_->cardinality = - (_set_->cardinality - entry->multiplicity) + multiplicity; + _set_->cardinality = (_set_->cardinality - entry->multiplicity) + multiplicity; entry->multiplicity = multiplicity; success: _set_->flag = CMC_FLAG_OK; @@ -461,8 +434,7 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity) _set_->flag = CMC_FLAG_INVALID; return 0; } - struct hashmultiset *_new_set_ = hms_new_custom( - capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); + struct hashmultiset *_new_set_ = hms_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!_new_set_) { _set_->flag = CMC_FLAG_ERROR; @@ -471,8 +443,7 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity) struct hashmultiset_iter iter = hms_iter_start(_set_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { - hms_insert_many(_new_set_, hms_iter_value(&iter), - hms_iter_multiplicity(&iter)); + hms_insert_many(_new_set_, hms_iter_value(&iter), hms_iter_multiplicity(&iter)); } if (_set_->count != _new_set_->count) { @@ -496,8 +467,7 @@ success: struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) { struct hashmultiset *result = - hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, - _set_->alloc, _set_->callbacks); + hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, _set_->callbacks); if (!result) { _set_->flag = CMC_FLAG_ERROR; @@ -524,8 +494,7 @@ struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) } } else - memcpy(result->buffer, _set_->buffer, - sizeof(struct hashmultiset_entry) * _set_->capacity); + memcpy(result->buffer, _set_->buffer, sizeof(struct hashmultiset_entry) * _set_->capacity); result->count = _set_->count; result->cardinality = _set_->cardinality; _set_->flag = CMC_FLAG_OK; @@ -544,8 +513,7 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { - struct hashmultiset_entry *entry = - hms_impl_get_entry(_set2_, hms_iter_value(&iter)); + struct hashmultiset_entry *entry = hms_impl_get_entry(_set2_, hms_iter_value(&iter)); if (!entry) return 0; if (entry->multiplicity != hms_iter_multiplicity(&iter)) @@ -553,12 +521,10 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) } return 1; } -struct hashmultiset *hms_union(struct hashmultiset *_set1_, - struct hashmultiset *_set2_) +struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); @@ -582,16 +548,13 @@ struct hashmultiset *hms_union(struct hashmultiset *_set1_, _set_r_->callbacks = _set1_->callbacks; return _set_r_; } -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, - struct hashmultiset *_set2_) +struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); - struct hashmultiset *_set_A_ = - _set1_->count < _set2_->count ? _set1_ : _set2_; + struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; struct hashmultiset_iter iter = hms_iter_start(_set_A_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) @@ -605,12 +568,10 @@ struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, _set_r_->callbacks = _set1_->callbacks; return _set_r_; } -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, - struct hashmultiset *_set2_) +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter = hms_iter_start(_set1_); @@ -625,35 +586,29 @@ struct hashmultiset *hms_difference(struct hashmultiset *_set1_, _set_r_->callbacks = _set1_->callbacks; return _set_r_; } -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, - struct hashmultiset *_set2_) +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); struct hashmultiset_iter iter2 = hms_iter_start(_set2_); for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { - hms_insert_many(_set_r_, hms_iter_value(&iter1), - hms_iter_multiplicity(&iter1)); + hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); } for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { - hms_insert_many(_set_r_, hms_iter_value(&iter2), - hms_iter_multiplicity(&iter2)); + hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); } _set_r_->callbacks = _set1_->callbacks; return _set_r_; } -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, - struct hashmultiset *_set2_) +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); @@ -708,8 +663,7 @@ _Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { return hms_is_subset(_set2_, _set1_); } -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, - struct hashmultiset *_set2_) +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { if (_set1_->count >= _set2_->count) return 0; @@ -731,13 +685,11 @@ _Bool hms_is_proper_subset(struct hashmultiset *_set1_, } return 1; } -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, - struct hashmultiset *_set2_) +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { return hms_is_proper_subset(_set2_, _set1_); } -_Bool hms_is_disjointset(struct hashmultiset *_set1_, - struct hashmultiset *_set2_) +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { if (hms_empty(_set1_)) return 1; @@ -952,9 +904,7 @@ static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) return 0; return entry->multiplicity; } -static struct hashmultiset_entry * -hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, - _Bool *new_node) +static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) { *new_node = 0; struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); @@ -986,8 +936,7 @@ hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, { pos++; target = &(_set_->buffer[pos % _set_->capacity]); - if (target->state == CMC_ES_EMPTY || - target->state == CMC_ES_DELETED) + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->value = value; target->multiplicity = curr_mul; @@ -1016,8 +965,7 @@ hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _set_->count++; return to_return; } -static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, - size_t value) +static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value) { size_t hash = _set_->f_val->hash(value); size_t pos = hash % _set_->capacity; @@ -1033,8 +981,7 @@ static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, } static size_t hms_impl_calculate_size(size_t required) { - const size_t count = - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; diff --git a/tests/main/src/hashset.c b/tests/main/src/hashset.c index 94fb021..f4b278f 100644 --- a/tests/main/src/hashset.c +++ b/tests/main/src/hashset.c @@ -39,16 +39,12 @@ struct hashset_iter _Bool start; _Bool end; }; -struct hashset *hs_new(size_t capacity, double load, - struct hashset_fval *f_val); -struct hashset *hs_new_custom(size_t capacity, double load, - struct hashset_fval *f_val, - struct cmc_alloc_node *alloc, +struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val); +struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void hs_clear(struct hashset *_set_); void hs_free(struct hashset *_set_); -void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool hs_insert(struct hashset *_set_, size_t value); _Bool hs_remove(struct hashset *_set_, size_t value); _Bool hs_max(struct hashset *_set_, size_t *value); @@ -68,8 +64,7 @@ _Bool hs_print(struct hashset *_set_, FILE *fptr); struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_symmetric_difference(struct hashset *_set1_, - struct hashset *_set2_); +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); _Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); _Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); _Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); @@ -88,8 +83,7 @@ _Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps); _Bool hs_iter_go_to(struct hashset_iter *iter, size_t index); size_t hs_iter_value(struct hashset_iter *iter); size_t hs_iter_index(struct hashset_iter *iter); -static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, - size_t value); +static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value); static size_t hs_impl_calculate_size(size_t required); static struct hashset_iter hs_impl_it_start(struct hashset *_set_); static struct hashset_iter hs_impl_it_end(struct hashset *_set_); @@ -121,9 +115,7 @@ struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val) _set_->callbacks = ((void *)0); return _set_; } -struct hashset *hs_new_custom(size_t capacity, double load, - struct hashset_fval *f_val, - struct cmc_alloc_node *alloc, +struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity == 0 || load <= 0 || load >= 1) @@ -186,8 +178,7 @@ void hs_free(struct hashset *_set_) _set_->alloc->free(_set_->buffer); _set_->alloc->free(_set_); } -void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _set_->alloc = &cmc_alloc_node_default; @@ -224,8 +215,7 @@ _Bool hs_insert(struct hashset *_set_, size_t value) { pos++; target = &(_set_->buffer[pos % _set_->capacity]); - if (target->state == CMC_ES_EMPTY || - target->state == CMC_ES_DELETED) + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->value = value; target->dist = pos - original_pos; @@ -371,8 +361,7 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity) _set_->flag = CMC_FLAG_INVALID; return 0; } - struct hashset *_new_set_ = hs_new_custom( - capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); + struct hashset *_new_set_ = hs_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!_new_set_) { _set_->flag = CMC_FLAG_ALLOC; @@ -406,8 +395,7 @@ success: struct hashset *hs_copy_of(struct hashset *_set_) { struct hashset *result = - hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, - _set_->alloc, _set_->callbacks); + hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, _set_->callbacks); if (!result) { _set_->flag = CMC_FLAG_ERROR; @@ -433,8 +421,7 @@ struct hashset *hs_copy_of(struct hashset *_set_) } } else - memcpy(result->buffer, _set_->buffer, - sizeof(struct hashset_entry) * _set_->capacity); + memcpy(result->buffer, _set_->buffer, sizeof(struct hashset_entry) * _set_->capacity); result->count = _set_->count; _set_->flag = CMC_FLAG_OK; return result; @@ -457,9 +444,7 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) } struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) { - struct hashset *_set_r_ = - hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; @@ -481,9 +466,7 @@ struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) } struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_) { - struct hashset *_set_r_ = - hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; @@ -504,9 +487,7 @@ struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_) } struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) { - struct hashset *_set_r_ = - hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; @@ -523,12 +504,9 @@ struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) _set_r_->callbacks = _set1_->callbacks; return _set_r_; } -struct hashset *hs_symmetric_difference(struct hashset *_set1_, - struct hashset *_set2_) +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_) { - struct hashset *_set_r_ = - hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, - _set1_->alloc, ((void *)0)); + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; @@ -803,8 +781,7 @@ size_t hs_iter_index(struct hashset_iter *iter) { return iter->index; } -static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, - size_t value) +static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value) { size_t hash = _set_->f_val->hash(value); size_t pos = hash % _set_->capacity; @@ -820,8 +797,7 @@ static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, } static size_t hs_impl_calculate_size(size_t required) { - const size_t count = - sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; diff --git a/tests/main/src/heap.c b/tests/main/src/heap.c index 4c04496..37b968d 100644 --- a/tests/main/src/heap.c +++ b/tests/main/src/heap.c @@ -30,15 +30,12 @@ struct heap_iter _Bool start; _Bool end; }; -struct heap *h_new(size_t capacity, enum cmc_heap_order HO, - struct heap_fval *f_val); -struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, - struct heap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val); +struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void h_clear(struct heap *_heap_); void h_free(struct heap *_heap_); -void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool h_insert(struct heap *_heap_, size_t value); _Bool h_remove(struct heap *_heap_); size_t h_peek(struct heap *_heap_); @@ -68,8 +65,7 @@ size_t h_iter_value(struct heap_iter *iter); size_t h_iter_index(struct heap_iter *iter); static void h_impl_float_up(struct heap *_heap_, size_t index); static void h_impl_float_down(struct heap *_heap_, size_t index); -struct heap *h_new(size_t capacity, enum cmc_heap_order HO, - struct heap_fval *f_val) +struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; if (capacity < 1) @@ -96,9 +92,8 @@ struct heap *h_new(size_t capacity, enum cmc_heap_order HO, _heap_->callbacks = ((void *)0); return _heap_; } -struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, - struct heap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity < 1) return ((void *)0); @@ -151,8 +146,7 @@ void h_free(struct heap *_heap_) _heap_->alloc->free(_heap_->buffer); _heap_->alloc->free(_heap_); } -void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _heap_->alloc = &cmc_alloc_node_default; @@ -252,8 +246,7 @@ _Bool h_resize(struct heap *_heap_, size_t capacity) _heap_->flag = CMC_FLAG_INVALID; return 0; } - size_t *new_buffer = - _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity); + size_t *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _heap_->flag = CMC_FLAG_ALLOC; @@ -268,9 +261,7 @@ success: } struct heap *h_copy_of(struct heap *_heap_) { - struct heap *result = - h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, - _heap_->callbacks); + struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, _heap_->callbacks); if (!result) { _heap_->flag = CMC_FLAG_ERROR; @@ -454,13 +445,11 @@ static void h_impl_float_down(struct heap *_heap_, size_t index) size_t L = 2 * index + 1; size_t R = 2 * index + 2; size_t C = index; - if (L < _heap_->count && - _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) + if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) { C = L; } - if (R < _heap_->count && - _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) + if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) { C = R; } diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index 62522f1..f72ad33 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -31,14 +31,11 @@ struct intervalheap_iter _Bool end; }; struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val); -struct intervalheap *ih_new_custom(size_t capacity, - struct intervalheap_fval *f_val, - struct cmc_alloc_node *alloc, +struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void ih_clear(struct intervalheap *_heap_); void ih_free(struct intervalheap *_heap_); -void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool ih_insert(struct intervalheap *_heap_, size_t value); _Bool ih_remove_max(struct intervalheap *_heap_); _Bool ih_remove_min(struct intervalheap *_heap_); @@ -100,9 +97,7 @@ struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) _heap_->callbacks = ((void *)0); return _heap_; } -struct intervalheap *ih_new_custom(size_t capacity, - struct intervalheap_fval *f_val, - struct cmc_alloc_node *alloc, +struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity == 0 || capacity == 0xffffffffffffffffULL) @@ -156,8 +151,7 @@ void ih_free(struct intervalheap *_heap_) _heap_->alloc->free(_heap_->buffer); _heap_->alloc->free(_heap_); } -void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _heap_->alloc = &cmc_alloc_node_default; @@ -405,8 +399,7 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity) return 0; } capacity += capacity % 2; - size_t(*new_buffer)[2] = - _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity); + size_t(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity); if (!new_buffer) { _heap_->flag = CMC_FLAG_ALLOC; @@ -414,8 +407,7 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity) } if (capacity > _heap_->capacity) { - memset(new_buffer + _heap_->capacity, 0, - sizeof(size_t[2]) * (capacity - _heap_->capacity)); + memset(new_buffer + _heap_->capacity, 0, sizeof(size_t[2]) * (capacity - _heap_->capacity)); } _heap_->buffer = new_buffer; _heap_->capacity = capacity; @@ -427,16 +419,14 @@ success: } struct intervalheap *ih_copy_of(struct intervalheap *_heap_) { - struct intervalheap *result = - _heap_->alloc->malloc(sizeof(struct intervalheap)); + struct intervalheap *result = _heap_->alloc->malloc(sizeof(struct intervalheap)); if (!result) { _heap_->flag = CMC_FLAG_ALLOC; return ((void *)0); } memcpy(result, _heap_, sizeof(struct intervalheap)); - result->buffer = - _heap_->alloc->malloc(sizeof(size_t[2]) * _heap_->capacity); + result->buffer = _heap_->alloc->malloc(sizeof(size_t[2]) * _heap_->capacity); if (!result->buffer) { _heap_->alloc->free(result); @@ -446,12 +436,10 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_) if (_heap_->f_val->cpy) { for (size_t i = 0; i < _heap_->count; i++) - result->buffer[i / 2][i % 2] = - _heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]); + result->buffer[i / 2][i % 2] = _heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]); } else - memcpy(result->buffer, _heap_->buffer, - sizeof(size_t[2]) * _heap_->capacity); + memcpy(result->buffer, _heap_->buffer, sizeof(size_t[2]) * _heap_->capacity); result->capacity = _heap_->capacity; result->size = _heap_->size; result->count = _heap_->count; @@ -666,11 +654,9 @@ static void ih_impl_float_down_max(struct intervalheap *_heap_) size_t(*L)[2] = &(_heap_->buffer[L_index]); size_t(*R)[2] = &(_heap_->buffer[R_index]); if (R_index == _heap_->size - 1 && _heap_->count % 2 != 0) - child = _heap_->f_val->cmp((*L)[1], (*R)[0]) > 0 ? L_index - : R_index; + child = _heap_->f_val->cmp((*L)[1], (*R)[0]) > 0 ? L_index : R_index; else - child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index - : R_index; + child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index; } else child = L_index; @@ -716,8 +702,7 @@ static void ih_impl_float_down_min(struct intervalheap *_heap_) { size_t(*L)[2] = &(_heap_->buffer[L_index]); size_t(*R)[2] = &(_heap_->buffer[R_index]); - child = - _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index; + child = _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index; } else child = L_index; diff --git a/tests/main/src/linkedlist.c b/tests/main/src/linkedlist.c index 2fe8dbd..e07b066 100644 --- a/tests/main/src/linkedlist.c +++ b/tests/main/src/linkedlist.c @@ -37,13 +37,11 @@ struct linkedlist_iter _Bool end; }; struct linkedlist *ll_new(struct linkedlist_fval *f_val); -struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, - struct cmc_alloc_node *alloc, +struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void ll_clear(struct linkedlist *_list_); void ll_free(struct linkedlist *_list_); -void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool ll_push_front(struct linkedlist *_list_, size_t value); _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index); _Bool ll_push_back(struct linkedlist *_list_, size_t value); @@ -67,10 +65,8 @@ void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); struct linkedlist_node *ll_head(struct linkedlist *_list_); struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); struct linkedlist_node *ll_tail(struct linkedlist *_list_); -_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, - size_t value); -_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, - size_t value); +_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); _Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); _Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); _Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); @@ -108,8 +104,7 @@ struct linkedlist *ll_new(struct linkedlist_fval *f_val) _list_->callbacks = ((void *)0); return _list_; } -struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, - struct cmc_alloc_node *alloc, +struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!f_val) @@ -151,8 +146,7 @@ void ll_free(struct linkedlist *_list_) ll_clear(_list_); _list_->alloc->free(_list_); } -void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _list_->alloc = &cmc_alloc_node_default; @@ -400,8 +394,7 @@ int ll_flag(struct linkedlist *_list_) } struct linkedlist *ll_copy_of(struct linkedlist *_list_) { - struct linkedlist *result = - ll_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks); + struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks); if (!result) return ((void *)0); struct linkedlist_node *scan = _list_->head; @@ -448,8 +441,7 @@ _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) } struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) { - struct linkedlist_node *_node_ = - _list_->alloc->malloc(sizeof(struct linkedlist_node)); + struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node)); if (!_node_) { _list_->flag = CMC_FLAG_ALLOC; @@ -504,8 +496,7 @@ struct linkedlist_node *ll_tail(struct linkedlist *_list_) { return _list_->tail; } -_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, - size_t value) +_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value) { struct linkedlist_node *new_node = ll_new_node(_owner_, value); if (!new_node) @@ -521,8 +512,7 @@ _Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, _owner_->flag = CMC_FLAG_OK; return 1; } -_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, - size_t value) +_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value) { struct linkedlist_node *new_node = ll_new_node(_owner_, value); if (!new_node) diff --git a/tests/main/src/list.c b/tests/main/src/list.c index b0e8824..eeca0cf 100644 --- a/tests/main/src/list.c +++ b/tests/main/src/list.c @@ -30,13 +30,11 @@ struct list_iter _Bool end; }; struct list *l_new(size_t capacity, struct list_fval *f_val); -struct list *l_new_custom(size_t capacity, struct list_fval *f_val, - struct cmc_alloc_node *alloc, +struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void l_clear(struct list *_list_); void l_free(struct list *_list_); -void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool l_push_front(struct list *_list_, size_t value); _Bool l_push_at(struct list *_list_, size_t value, size_t index); _Bool l_push_back(struct list *_list_, size_t value); @@ -44,8 +42,7 @@ _Bool l_pop_front(struct list *_list_); _Bool l_pop_at(struct list *_list_, size_t index); _Bool l_pop_back(struct list *_list_); _Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, - size_t index); +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); _Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); _Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); @@ -102,8 +99,7 @@ struct list *l_new(size_t capacity, struct list_fval *f_val) _list_->callbacks = ((void *)0); return _list_; } -struct list *l_new_custom(size_t capacity, struct list_fval *f_val, - struct cmc_alloc_node *alloc, +struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity < 1) @@ -150,8 +146,7 @@ void l_free(struct list *_list_) _list_->alloc->free(_list_->buffer); _list_->alloc->free(_list_); } -void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _list_->alloc = &cmc_alloc_node_default; @@ -169,8 +164,7 @@ _Bool l_push_front(struct list *_list_, size_t value) } if (!l_empty(_list_)) { - memmove(_list_->buffer + 1, _list_->buffer, - _list_->count * sizeof(size_t)); + memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(size_t)); } _list_->buffer[0] = value; _list_->count++; @@ -191,8 +185,7 @@ _Bool l_push_at(struct list *_list_, size_t value, size_t index) if (!l_resize(_list_, _list_->count * 2)) return 0; } - memmove(_list_->buffer + index + 1, _list_->buffer + index, - (_list_->count - index) * sizeof(size_t)); + memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); _list_->buffer[index] = value; _list_->count++; _list_->flag = CMC_FLAG_OK; @@ -220,8 +213,7 @@ _Bool l_pop_front(struct list *_list_) _list_->flag = CMC_FLAG_EMPTY; return 0; } - memmove(_list_->buffer, _list_->buffer + 1, - (_list_->count - 1) * sizeof(size_t)); + memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) @@ -240,8 +232,7 @@ _Bool l_pop_at(struct list *_list_, size_t index) _list_->flag = CMC_FLAG_RANGE; return 0; } - memmove(_list_->buffer + index, _list_->buffer + index + 1, - (_list_->count - index - 1) * sizeof(size_t)); + memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) @@ -270,8 +261,7 @@ _Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) if (!l_resize(_list_, _list_->count + size)) return 0; } - memmove(_list_->buffer + size, _list_->buffer, - _list_->count * sizeof(size_t)); + memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); memcpy(_list_->buffer, values, size * sizeof(size_t)); _list_->count += size; _list_->flag = CMC_FLAG_OK; @@ -279,8 +269,7 @@ _Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) _list_->callbacks->create(); return 1; } -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, - size_t index) +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index) { if (size == 0) { @@ -301,8 +290,7 @@ _Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, if (!l_resize(_list_, _list_->count + size)) return 0; } - memmove(_list_->buffer + index + size, _list_->buffer + index, - (_list_->count - index) * sizeof(size_t)); + memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); memcpy(_list_->buffer + index, values, size * sizeof(size_t)); _list_->count += size; _list_->flag = CMC_FLAG_OK; @@ -342,8 +330,7 @@ _Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) return 0; } size_t length = (to - from + 1); - memmove(_list_->buffer + from, _list_->buffer + to + 1, - (_list_->count - to - 1) * sizeof(size_t)); + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); _list_->count -= to - from + 1; _list_->flag = CMC_FLAG_OK; @@ -364,16 +351,14 @@ struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) return ((void *)0); } size_t length = to - from + 1; - struct list *result = - l_new_custom(length, _list_->f_val, _list_->alloc, _list_->callbacks); + struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, _list_->callbacks); if (!result) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); - memmove(_list_->buffer + from, _list_->buffer + to + 1, - (_list_->count - to - 1) * sizeof(size_t)); + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); _list_->count -= length; result->count = length; @@ -520,8 +505,7 @@ _Bool l_resize(struct list *_list_, size_t capacity) _list_->flag = CMC_FLAG_INVALID; return 0; } - size_t *new_buffer = - _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); + size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _list_->flag = CMC_FLAG_ALLOC; @@ -535,8 +519,7 @@ _Bool l_resize(struct list *_list_, size_t capacity) } struct list *l_copy_of(struct list *_list_) { - struct list *result = l_new_custom(_list_->capacity, _list_->f_val, - _list_->alloc, _list_->callbacks); + struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, _list_->callbacks); if (!result) { _list_->flag = CMC_FLAG_ALLOC; @@ -566,26 +549,6 @@ _Bool l_equals(struct list *_list1_, struct list *_list2_) } return 1; } -struct cmc_string l_to_string(struct list *_list_) -{ - struct cmc_string str; - struct list *l_ = _list_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_list, - "CMC_PARAM_SNAME((l, list, , , size_t))", - "CMC_PARAM_V((l, list, , , size_t))", l_, l_->buffer, - l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, - l_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool l_print(struct list *_list_, FILE *fptr) -{ - for (size_t i = 0; i < _list_->count; i++) - { - if (!_list_->f_val->str(fptr, _list_->buffer[i])) - return 0; - } - return 1; -} struct list_iter l_iter_start(struct list *target) { struct list_iter iter; diff --git a/tests/main/src/queue.c b/tests/main/src/queue.c index 73abdce..b0a4f7d 100644 --- a/tests/main/src/queue.c +++ b/tests/main/src/queue.c @@ -33,13 +33,11 @@ struct queue_iter _Bool end; }; struct queue *q_new(size_t capacity, struct queue_fval *f_val); -struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, - struct cmc_alloc_node *alloc, +struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void q_clear(struct queue *_queue_); void q_free(struct queue *_queue_); -void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool q_enqueue(struct queue *_queue_, size_t value); _Bool q_dequeue(struct queue *_queue_); size_t q_peek(struct queue *_queue_); @@ -94,8 +92,7 @@ struct queue *q_new(size_t capacity, struct queue_fval *f_val) _queue_->callbacks = ((void *)0); return _queue_; } -struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, - struct cmc_alloc_node *alloc, +struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity < 1) @@ -152,8 +149,7 @@ void q_free(struct queue *_queue_) _queue_->alloc->free(_queue_->buffer); _queue_->alloc->free(_queue_); } -void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _queue_->alloc = &cmc_alloc_node_default; @@ -170,8 +166,7 @@ _Bool q_enqueue(struct queue *_queue_, size_t value) return 0; } _queue_->buffer[_queue_->back] = value; - _queue_->back = - (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; + _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; _queue_->count++; _queue_->flag = CMC_FLAG_OK; if (_queue_->callbacks && _queue_->callbacks->create) @@ -186,8 +181,7 @@ _Bool q_dequeue(struct queue *_queue_) return 0; } _queue_->buffer[_queue_->front] = (size_t){ 0 }; - _queue_->front = - (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; + _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; _queue_->count--; _queue_->flag = CMC_FLAG_OK; if (_queue_->callbacks && _queue_->callbacks->delete) @@ -276,8 +270,7 @@ success: } struct queue *q_copy_of(struct queue *_queue_) { - struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, - _queue_->alloc, _queue_->callbacks); + struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, _queue_->callbacks); if (!result) { _queue_->flag = CMC_FLAG_ERROR; @@ -312,8 +305,7 @@ _Bool q_equals(struct queue *_queue1_, struct queue *_queue2_) if (_queue1_->count != _queue2_->count) return 0; size_t i, j, k; - for (i = _queue1_->front, j = _queue2_->front, k = 0; k < _queue1_->count; - k++) + for (i = _queue1_->front, j = _queue2_->front, k = 0; k < _queue1_->count; k++) { if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) return 0; @@ -322,27 +314,6 @@ _Bool q_equals(struct queue *_queue1_, struct queue *_queue2_) } return 1; } -struct cmc_string q_to_string(struct queue *_queue_) -{ - struct cmc_string str; - struct queue *q_ = _queue_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_queue, - "CMC_PARAM_SNAME((q, queue, , , size_t))", - "CMC_PARAM_V((q, queue, , , size_t))", q_, q_->buffer, - q_->capacity, q_->count, q_->front, q_->back, q_->flag, - q_->f_val, q_->alloc, q_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool q_print(struct queue *_queue_, FILE *fptr) -{ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) - return 0; - i = (i + 1) % _queue_->capacity; - } - return 1; -} struct queue_iter q_iter_start(struct queue *target) { struct queue_iter iter; @@ -433,8 +404,7 @@ _Bool q_iter_prev(struct queue_iter *iter) return 0; } iter->end = q_empty(iter->target); - iter->cursor = - (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; iter->index--; return 1; } diff --git a/tests/main/src/sortedlist.c b/tests/main/src/sortedlist.c index 61c1141..cb2f97f 100644 --- a/tests/main/src/sortedlist.c +++ b/tests/main/src/sortedlist.c @@ -31,13 +31,11 @@ struct sortedlist_iter _Bool end; }; struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val); -struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, - struct cmc_alloc_node *alloc, +struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void sl_clear(struct sortedlist *_list_); void sl_free(struct sortedlist *_list_); -void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool sl_insert(struct sortedlist *_list_, size_t value); _Bool sl_remove(struct sortedlist *_list_, size_t index); size_t sl_max(struct sortedlist *_list_); @@ -69,14 +67,10 @@ _Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps); _Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index); size_t sl_iter_value(struct sortedlist_iter *iter); size_t sl_iter_index(struct sortedlist_iter *iter); -static size_t sl_impl_binary_search_first(struct sortedlist *_list_, - size_t value); -static size_t sl_impl_binary_search_last(struct sortedlist *_list_, - size_t value); -void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), - size_t low, size_t high); -void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), - size_t low, size_t high); +static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value); +static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value); +void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); +void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val) { struct cmc_alloc_node *alloc = &cmc_alloc_node_default; @@ -102,8 +96,7 @@ struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val) _list_->callbacks = ((void *)0); return _list_; } -struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, - struct cmc_alloc_node *alloc, +struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity < 1) @@ -149,8 +142,7 @@ void sl_free(struct sortedlist *_list_) _list_->alloc->free(_list_->buffer); _list_->alloc->free(_list_); } -void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _list_->alloc = &cmc_alloc_node_default; @@ -185,8 +177,7 @@ _Bool sl_remove(struct sortedlist *_list_, size_t index) _list_->flag = CMC_FLAG_RANGE; return 0; } - memmove(_list_->buffer + index, _list_->buffer + index + 1, - (_list_->count - index) * sizeof(size_t)); + memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if (_list_->callbacks && _list_->callbacks->delete) @@ -288,8 +279,7 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity) _list_->flag = CMC_FLAG_INVALID; return 0; } - size_t *new_buffer = - _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); + size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _list_->flag = CMC_FLAG_ALLOC; @@ -308,15 +298,13 @@ void sl_sort(struct sortedlist *_list_) _list_->flag = CMC_FLAG_OK; if (!_list_->is_sorted && _list_->count > 1) { - sl_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, - _list_->count - 1); + sl_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, _list_->count - 1); _list_->is_sorted = 1; } } struct sortedlist *sl_copy_of(struct sortedlist *_list_) { - struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, - _list_->alloc, _list_->callbacks); + struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, _list_->callbacks); if (!result) { _list_->flag = CMC_FLAG_ERROR; @@ -346,28 +334,6 @@ _Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_) } return 1; } -struct cmc_string sl_to_string(struct sortedlist *_list_) -{ - struct cmc_string str; - struct sortedlist *l_ = _list_; - int n = - snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_sortedlist, - "CMC_PARAM_SNAME((sl, sortedlist, , , size_t))", - "CMC_PARAM_V((sl, sortedlist, , , size_t))", l_, l_->buffer, - l_->capacity, l_->count, l_->is_sorted ? "true" : "false", - l_->flag, l_->f_val, l_->alloc, l_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool sl_print(struct sortedlist *_list_, FILE *fptr) -{ - sl_sort(_list_); - for (size_t i = 0; i < _list_->count; i++) - { - if (!_list_->f_val->str(fptr, _list_->buffer[i])) - return 0; - } - return 1; -} struct sortedlist_iter sl_iter_start(struct sortedlist *target) { sl_sort(target); @@ -496,8 +462,7 @@ size_t sl_iter_index(struct sortedlist_iter *iter) { return iter->cursor; } -static size_t sl_impl_binary_search_first(struct sortedlist *_list_, - size_t value) +static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value) { if (sl_empty(_list_)) return 1; @@ -515,8 +480,7 @@ static size_t sl_impl_binary_search_first(struct sortedlist *_list_, return L; return _list_->count; } -static size_t sl_impl_binary_search_last(struct sortedlist *_list_, - size_t value) +static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value) { if (sl_empty(_list_)) return 1; @@ -534,8 +498,7 @@ static size_t sl_impl_binary_search_last(struct sortedlist *_list_, return L - 1; return _list_->count; } -void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), - size_t low, size_t high) +void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) { while (low < high) { @@ -574,8 +537,7 @@ void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), } } } -void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), - size_t low, size_t high) +void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) { for (size_t i = low + 1; i <= high; i++) { diff --git a/tests/main/src/stack.c b/tests/main/src/stack.c index b98f023..69ab69f 100644 --- a/tests/main/src/stack.c +++ b/tests/main/src/stack.c @@ -30,13 +30,11 @@ struct stack_iter _Bool end; }; struct stack *s_new(size_t capacity, struct stack_fval *f_val); -struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, - struct cmc_alloc_node *alloc, +struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void s_clear(struct stack *_stack_); void s_free(struct stack *_stack_); -void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool s_push(struct stack *_stack_, size_t value); _Bool s_pop(struct stack *_stack_); size_t s_top(struct stack *_stack_); @@ -89,8 +87,7 @@ struct stack *s_new(size_t capacity, struct stack_fval *f_val) _stack_->callbacks = ((void *)0); return _stack_; } -struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, - struct cmc_alloc_node *alloc, +struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (capacity < 1) @@ -137,8 +134,7 @@ void s_free(struct stack *_stack_) _stack_->alloc->free(_stack_->buffer); _stack_->alloc->free(_stack_); } -void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _stack_->alloc = &cmc_alloc_node_default; @@ -230,8 +226,7 @@ _Bool s_resize(struct stack *_stack_, size_t capacity) _stack_->flag = CMC_FLAG_INVALID; return 0; } - size_t *new_buffer = - _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity); + size_t *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _stack_->flag = CMC_FLAG_ALLOC; @@ -247,8 +242,7 @@ success: } struct stack *s_copy_of(struct stack *_stack_) { - struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, - _stack_->alloc, _stack_->callbacks); + struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, _stack_->callbacks); if (!result) { _stack_->flag = CMC_FLAG_ERROR; @@ -260,8 +254,7 @@ struct stack *s_copy_of(struct stack *_stack_) result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); } else - memcpy(result->buffer, _stack_->buffer, - sizeof(size_t) * _stack_->count); + memcpy(result->buffer, _stack_->buffer, sizeof(size_t) * _stack_->count); result->count = _stack_->count; _stack_->flag = CMC_FLAG_OK; return result; @@ -279,26 +272,6 @@ _Bool s_equals(struct stack *_stack1_, struct stack *_stack2_) } return 1; } -struct cmc_string s_to_string(struct stack *_stack_) -{ - struct cmc_string str; - struct stack *s_ = _stack_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_stack, - "CMC_PARAM_SNAME((s, stack, , , size_t))", - "CMC_PARAM_V((s, stack, , , size_t))", s_, s_->buffer, - s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, - s_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool s_print(struct stack *_stack_, FILE *fptr) -{ - for (size_t i = 0; i < _stack_->count; i++) - { - if (!_stack_->f_val->str(fptr, _stack_->buffer[i])) - return 0; - } - return 1; -} struct stack_iter s_iter_start(struct stack *target) { struct stack_iter iter; diff --git a/tests/main/src/treemap.c b/tests/main/src/treemap.c index 66d955f..2f16e80 100644 --- a/tests/main/src/treemap.c +++ b/tests/main/src/treemap.c @@ -51,17 +51,13 @@ struct treemap_iter _Bool end; }; struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val); -struct treemap *tm_new_custom(struct treemap_fkey *f_key, - struct treemap_fval *f_val, - struct cmc_alloc_node *alloc, +struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void tm_clear(struct treemap *_map_); void tm_free(struct treemap *_map_); -void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool tm_insert(struct treemap *_map_, size_t key, size_t value); -_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, - size_t *old_value); +_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value); _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value); _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value); _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value); @@ -90,8 +86,7 @@ size_t tm_iter_key(struct treemap_iter *iter); size_t tm_iter_value(struct treemap_iter *iter); size_t *tm_iter_rvalue(struct treemap_iter *iter); size_t tm_iter_index(struct treemap_iter *iter); -static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, - size_t value); +static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value); static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key); static unsigned char tm_impl_h(struct treemap_node *node); static unsigned char tm_impl_hupdate(struct treemap_node *node); @@ -115,9 +110,7 @@ struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val) _map_->callbacks = ((void *)0); return _map_; } -struct treemap *tm_new_custom(struct treemap_fkey *f_key, - struct treemap_fval *f_val, - struct cmc_alloc_node *alloc, +struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!f_key || !f_val) @@ -198,8 +191,7 @@ void tm_free(struct treemap *_map_) tm_clear(_map_); _map_->alloc->free(_map_); } -void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _map_->alloc = &cmc_alloc_node_default; @@ -267,8 +259,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) _map_->callbacks->create(); return 1; } -_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, - size_t *old_value) +_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value) { struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) @@ -491,8 +482,7 @@ int tm_flag(struct treemap *_map_) } struct treemap *tm_copy_of(struct treemap *_map_) { - struct treemap *result = - tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); + struct treemap *result = tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; @@ -522,8 +512,7 @@ _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) struct treemap_iter iter = tm_iter_start(_map1_); for (; !tm_iter_at_end(&iter); tm_iter_next(&iter)) { - struct treemap_node *node = - tm_impl_get_node(_map2_, tm_iter_key(&iter)); + struct treemap_node *node = tm_impl_get_node(_map2_, tm_iter_key(&iter)); if (node == ((void *)0)) return 0; if (_map1_->f_val->cmp(node->value, tm_iter_value(&iter)) != 0) @@ -531,51 +520,6 @@ _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) } return 1; } -struct cmc_string tm_to_string(struct treemap *_map_) -{ - struct cmc_string str; - struct treemap *m_ = _map_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treemap, - "CMC_PARAM_SNAME((tm, treemap, , size_t, size_t))", - "CMC_PARAM_K((tm, treemap, , size_t, size_t))", - "CMC_PARAM_V((tm, treemap, , size_t, size_t))", m_, - m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, - m_->alloc, m_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool tm_print(struct treemap *_map_, FILE *fptr) -{ - struct treemap_node *root = _map_->root; - _Bool left_done = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - if (!_map_->f_key->str(fptr, root->key) && - !_map_->f_val->str(fptr, root->value)) - return 0; - left_done = 1; - if (root->right) - { - left_done = 0; - root = root->right; - } - else if (root->parent) - { - while (root->parent && root == root->parent->right) - root = root->parent; - if (!root->parent) - break; - root = root->parent; - } - else - break; - } - return 1; -} struct treemap_iter tm_iter_start(struct treemap *target) { struct treemap_iter iter; @@ -771,11 +715,9 @@ size_t tm_iter_index(struct treemap_iter *iter) { return iter->index; } -static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, - size_t value) +static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value) { - struct treemap_node *node = - _map_->alloc->malloc(sizeof(struct treemap_node)); + struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); if (!node) return ((void *)0); node->key = key; diff --git a/tests/main/src/treeset.c b/tests/main/src/treeset.c index 9952dc2..a1969ef 100644 --- a/tests/main/src/treeset.c +++ b/tests/main/src/treeset.c @@ -40,13 +40,11 @@ struct treeset_iter _Bool end; }; struct treeset *ts_new(struct treeset_fval *f_val); -struct treeset *ts_new_custom(struct treeset_fval *f_val, - struct cmc_alloc_node *alloc, +struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void ts_clear(struct treeset *_set_); void ts_free(struct treeset *_set_); -void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); +void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool ts_insert(struct treeset *_set_, size_t value); _Bool ts_remove(struct treeset *_set_, size_t value); _Bool ts_max(struct treeset *_set_, size_t *value); @@ -62,8 +60,7 @@ _Bool ts_print(struct treeset *_set_, FILE *fptr); struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_symmetric_difference(struct treeset *_set1_, - struct treeset *_set2_); +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); _Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); _Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); _Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); @@ -88,10 +85,8 @@ static inline size_t ts_impl_default_value(void) memset(&_empty_value_, 0, sizeof(size_t)); return _empty_value_; } -static struct treeset_node *ts_impl_new_node(struct treeset *_set_, - size_t value); -static struct treeset_node *ts_impl_get_node(struct treeset *_set_, - size_t value); +static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value); +static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value); static unsigned char ts_impl_h(struct treeset_node *node); static unsigned char ts_impl_hupdate(struct treeset_node *node); static void ts_impl_rotate_right(struct treeset_node **Z); @@ -113,9 +108,7 @@ struct treeset *ts_new(struct treeset_fval *f_val) _set_->callbacks = ((void *)0); return _set_; } -struct treeset *ts_new_custom(struct treeset_fval *f_val, - struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!f_val) return ((void *)0); @@ -190,8 +183,7 @@ void ts_free(struct treeset *_set_) ts_clear(_set_); _set_->alloc->free(_set_); } -void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) +void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { if (!alloc) _set_->alloc = &cmc_alloc_node_default; @@ -422,8 +414,7 @@ int ts_flag(struct treeset *_set_) } struct treeset *ts_copy_of(struct treeset *_set_) { - struct treeset *result = - ts_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks); + struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks); if (!result) { _set_->flag = CMC_FLAG_ERROR; @@ -457,52 +448,9 @@ _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) } return 1; } -struct cmc_string ts_to_string(struct treeset *_set_) -{ - struct cmc_string str; - struct treeset *s_ = _set_; - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treeset, - "CMC_PARAM_SNAME((ts, treeset, , , size_t))", - "CMC_PARAM_V((ts, treeset, , , size_t))", s_, s_->root, - s_->count, s_->flag, s_->f_val, s_->alloc, s_->callbacks); - return n >= 0 ? str : (struct cmc_string){ 0 }; -} -_Bool ts_print(struct treeset *_set_, FILE *fptr) -{ - struct treeset_node *root = _set_->root; - _Bool left_done = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - if (!_set_->f_val->str(fptr, root->value)) - return 0; - left_done = 1; - if (root->right) - { - left_done = 0; - root = root->right; - } - else if (root->parent) - { - while (root->parent && root == root->parent->right) - root = root->parent; - if (!root->parent) - break; - root = root->parent; - } - else - break; - } - return 1; -} struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = - ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); @@ -519,8 +467,7 @@ struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) } struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = - ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); if (!_set_r_) return ((void *)0); struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; @@ -536,8 +483,7 @@ struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) } struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = - ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); if (!_set_r_) return ((void *)0); struct treeset_iter iter = ts_iter_start(_set1_); @@ -549,11 +495,9 @@ struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) } return _set_r_; } -struct treeset *ts_symmetric_difference(struct treeset *_set1_, - struct treeset *_set2_) +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = - ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); @@ -811,11 +755,9 @@ size_t ts_iter_index(struct treeset_iter *iter) { return iter->index; } -static struct treeset_node *ts_impl_new_node(struct treeset *_set_, - size_t value) +static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value) { - struct treeset_node *node = - _set_->alloc->malloc(sizeof(struct treeset_node)); + struct treeset_node *node = _set_->alloc->malloc(sizeof(struct treeset_node)); if (!node) return ((void *)0); node->value = value; @@ -825,8 +767,7 @@ static struct treeset_node *ts_impl_new_node(struct treeset *_set_, node->height = 0; return node; } -static struct treeset_node *ts_impl_get_node(struct treeset *_set_, - size_t value) +static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value) { struct treeset_node *scan = _set_->root; while (scan != ((void *)0)) diff --git a/tests/main/unt/bitset.c b/tests/main/unt/bitset.c index 7c39da6..2524a4e 100644 --- a/tests/main/unt/bitset.c +++ b/tests/main/unt/bitset.c @@ -4,9 +4,8 @@ #include "../src/bitset.c" -struct cmc_alloc_node *bs_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free -}; +struct cmc_alloc_node *bs_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; CMC_CREATE_UNIT(BitSet, true, { const size_t word_bytes = sizeof(cmc_bitset_word); @@ -137,18 +136,14 @@ CMC_CREATE_UNIT(BitSet, true, { bs->buffer[0] = 0; cmc_assert(bs_set(bs, word_bits - 1)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, - ((cmc_bitset_word)1 << (word_bits - 1)), - bs->buffer[0]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)), bs->buffer[0]); cmc_assert(bs_set(bs, word_bits * 8 - 1)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, - ((cmc_bitset_word)1 << (word_bits - 1)), + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)), bs->buffer[bs_bit_to_index(word_bits * 8 - 1)]); cmc_assert(bs_set(bs, word_bits * 18 - 2)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, - ((cmc_bitset_word)1 << (word_bits - 2)), + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)), bs->buffer[bs_bit_to_index(word_bits * 18 - 2)]); bs_free(bs); @@ -177,28 +172,23 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_equals(uint8_t, 244, bs->buffer[0]); cmc_assert(bs_set_range(bs, word_bits * 6 - 2, word_bits * 6 - 2)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, - ((cmc_bitset_word)1 << (word_bits - 2)), + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)), bs->buffer[bs_bit_to_index(word_bits * 6 - 2)]); // Make sure we have at least word_bits * 40 slots bs_set(bs, word_bits * 40); cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0), - bs->buffer[bs_bit_to_index(word_bits * 20)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0), bs->buffer[bs_bit_to_index(word_bits * 20)]); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, - bs->buffer[bs_bit_to_index(word_bits * 20 - 1)]); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, - bs->buffer[bs_bit_to_index(word_bits * 21 + 1)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[bs_bit_to_index(word_bits * 20 - 1)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[bs_bit_to_index(word_bits * 21 + 1)]); cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1)); cmc_assert_equals(size_t, 100, bs->capacity); for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), - bs->buffer[i]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); bs_free(bs); }); @@ -239,8 +229,7 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1)); cmc_assert(bs_clear_range(bs, word_bits * 20, word_bits * 21 - 1)); - cmc_assert_equals(uint32_t, 0, - bs->buffer[bs_bit_to_index(word_bits * 20)]); + cmc_assert_equals(uint32_t, 0, bs->buffer[bs_bit_to_index(word_bits * 20)]); for (size_t i = 0; i < bs->capacity; i++) bs->buffer[i] = ~((cmc_bitset_word)0); @@ -309,8 +298,7 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_equals(size_t, 100, bs->capacity); for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), - bs->buffer[i]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); bs_free(bs); }); @@ -359,8 +347,7 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_equals(size_t, 100, bs->capacity); for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), - bs->buffer[i]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); cmc_assert(bs_put_range(bs, 0, word_bits * 100 - 1, false)); for (size_t i = 0; i < bs->capacity; i++) @@ -377,8 +364,7 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert(bs_set_all(bs)); for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), - bs->buffer[i]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); bs_free(bs); }); @@ -404,8 +390,7 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert(bs_flip_all(bs)); for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), - bs->buffer[i]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); cmc_assert(bs_flip_all(bs)); for (size_t i = 0; i < bs->capacity; i++) @@ -457,12 +442,10 @@ int main(void) { int result = BitSet() + BitSetIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | BitSet Suit : %-47s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/deque.c b/tests/main/unt/deque.c index 5706294..0bdb052 100644 --- a/tests/main/unt/deque.c +++ b/tests/main/unt/deque.c @@ -4,24 +4,17 @@ #include "../src/deque.c" -struct deque_fval *d_fval = &(struct deque_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct deque_fval *d_fval_counter = &(struct deque_fval){ .cmp = v_c_cmp, - .cpy = v_c_cpy, - .str = v_c_str, - .free = v_c_free, - .hash = v_c_hash, - .pri = v_c_pri }; - -struct cmc_alloc_node *d_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +struct deque_fval *d_fval = &(struct deque_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct deque_fval *d_fval_counter = &(struct deque_fval){ + .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri +}; + +struct cmc_alloc_node *d_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; + CMC_CREATE_UNIT(Deque, true, { CMC_CREATE_TEST(PFX##_new(), { struct deque *d = d_new(1000000, d_fval); @@ -50,8 +43,7 @@ CMC_CREATE_UNIT(Deque, true, { }); CMC_CREATE_TEST(PFX##_new_custom(), { - struct deque *d = - d_new_custom(1000000, d_fval, d_alloc_node, callbacks); + struct deque *d = d_new_custom(1000000, d_fval, d_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, d); cmc_assert_not_equals(ptr, NULL, d->buffer); @@ -176,8 +168,7 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(size_t, 1000, d_count(d)); size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) sum += d->buffer[i]; cmc_assert_equals(size_t, 500500, sum); @@ -219,8 +210,7 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(size_t, 1000, d_count(d)); size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) sum += d->buffer[i]; cmc_assert_equals(size_t, 500500, sum); @@ -319,8 +309,7 @@ CMC_CREATE_UNIT(Deque, true, { size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) { sum += d->buffer[i]; } @@ -367,8 +356,7 @@ CMC_CREATE_UNIT(Deque, true, { size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) { sum += d->buffer[i]; } @@ -417,8 +405,7 @@ CMC_CREATE_UNIT(Deque, true, { size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) { sum += d->buffer[i]; } @@ -437,8 +424,7 @@ CMC_CREATE_UNIT(Deque, true, { sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) { sum += d->buffer[i]; } @@ -482,8 +468,7 @@ CMC_CREATE_UNIT(Deque, true, { size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) { sum += d->buffer[i]; } @@ -502,8 +487,7 @@ CMC_CREATE_UNIT(Deque, true, { sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) { sum += d->buffer[i]; } @@ -802,8 +786,7 @@ CMC_CREATE_UNIT(Deque, true, { size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) { sum += d->buffer[i]; } @@ -1093,8 +1076,7 @@ CMC_CREATE_UNIT(Deque, true, { } size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; - i = (i + 1) % d->capacity, j++) + for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) sum += d->buffer[i]; cmc_assert_equals(size_t, 1200, d_count(d)); @@ -1732,12 +1714,10 @@ int main(void) { int result = Deque() + DequeIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | Deque Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/foreach.c b/tests/main/unt/foreach.c index ef93289..a37bca4 100644 --- a/tests/main/unt/foreach.c +++ b/tests/main/unt/foreach.c @@ -31,13 +31,12 @@ CMC_CREATE_UNIT(ForEach, true, { // }); CMC_CREATE_TEST(CMC, { - struct deque *d = - d_new(10000, &(struct deque_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct deque *d = d_new(10000, &(struct deque_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) d_push_back(d, i); @@ -81,20 +80,19 @@ CMC_CREATE_UNIT(ForEach, true, { // }); CMC_CREATE_TEST(CMC, { - struct hashmap *hm = - hm_new(10000, 0.6, - &(struct hashmap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }, - &(struct hashmap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct hashmap *hm = hm_new(10000, 0.6, + &(struct hashmap_fkey){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }, + &(struct hashmap_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) hm_insert(hm, i, i); @@ -123,20 +121,19 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct hashmultimap *hmm = - hmm_new(10000, 0.6, - &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }, - &(struct hashmultimap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct hashmultimap *hmm = hmm_new(10000, 0.6, + &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }, + &(struct hashmultimap_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) hmm_insert(hmm, i, i); @@ -165,14 +162,13 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct hashmultiset *hms = - hms_new(10000, 0.6, - &(struct hashmultiset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct hashmultiset *hms = hms_new(10000, 0.6, + &(struct hashmultiset_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) hms_insert_many(hms, i, i); @@ -201,14 +197,13 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct hashset *hs = - hs_new(10000, 0.6, - &(struct hashset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct hashset *hs = hs_new(10000, 0.6, + &(struct hashset_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) hs_insert(hs, i); @@ -260,13 +255,12 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct intervalheap *ih = - ih_new(10000, &(struct intervalheap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct intervalheap *ih = ih_new(10000, &(struct intervalheap_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) ih_insert(ih, i); @@ -289,13 +283,12 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct linkedlist *ll = - ll_new(&(struct linkedlist_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct linkedlist *ll = ll_new(&(struct linkedlist_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) ll_push_back(ll, i); @@ -318,13 +311,12 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct list *l = - l_new(10000, &(struct list_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct list *l = l_new(10000, &(struct list_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) l_push_back(l, i); @@ -347,13 +339,12 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct queue *q = - q_new(10000, &(struct queue_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct queue *q = q_new(10000, &(struct queue_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) q_enqueue(q, i); @@ -376,13 +367,12 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct sortedlist *sl = - sl_new(10000, &(struct sortedlist_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct sortedlist *sl = sl_new(10000, &(struct sortedlist_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) sl_insert(sl, i); @@ -405,13 +395,12 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct stack *s = - s_new(10000, &(struct stack_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct stack *s = s_new(10000, &(struct stack_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) s_push(s, i); @@ -434,19 +423,18 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct treemap *tm = - tm_new(&(struct treemap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }, - &(struct treemap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct treemap *tm = tm_new(&(struct treemap_fkey){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }, + &(struct treemap_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) tm_insert(tm, i, i); @@ -475,13 +463,12 @@ CMC_CREATE_UNIT(ForEach, true, { }); CMC_CREATE_TEST(CMC, { - struct treeset *ts = - ts_new(&(struct treeset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); + struct treeset *ts = ts_new(&(struct treeset_fval){ .cmp = cmc_size_cmp, + .cpy = NULL, + .str = cmc_size_str, + .free = NULL, + .hash = cmc_size_hash, + .pri = cmc_size_cmp }); for (size_t i = 1; i <= 10000; i++) ts_insert(ts, i); @@ -509,12 +496,10 @@ int main(void) { int result = ForEach(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | ForEach Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/hashbidimap.c b/tests/main/unt/hashbidimap.c index 40f139f..3d73272 100644 --- a/tests/main/unt/hashbidimap.c +++ b/tests/main/unt/hashbidimap.c @@ -4,42 +4,25 @@ #include "../src/hashbidimap.c" -struct hashbidimap_fkey *hbm_fkey = - &(struct hashbidimap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct hashbidimap_fval *hbm_fval = - &(struct hashbidimap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct hashbidimap_fkey *hbm_fkey_counter = - &(struct hashbidimap_fkey){ .cmp = k_c_cmp, - .cpy = k_c_cpy, - .str = k_c_str, - .free = k_c_free, - .hash = k_c_hash, - .pri = k_c_pri }; - -struct hashbidimap_fval *hbm_fval_counter = - &(struct hashbidimap_fval){ .cmp = v_c_cmp, - .cpy = v_c_cpy, - .str = v_c_str, - .free = v_c_free, - .hash = v_c_hash, - .pri = v_c_pri }; - -struct cmc_alloc_node *hbm_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +struct hashbidimap_fkey *hbm_fkey = &(struct hashbidimap_fkey){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct hashbidimap_fval *hbm_fval = &(struct hashbidimap_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; + +struct hashbidimap_fkey *hbm_fkey_counter = &(struct hashbidimap_fkey){ + .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri +}; + +struct hashbidimap_fval *hbm_fval_counter = &(struct hashbidimap_fval){ + .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri +}; + +struct cmc_alloc_node *hbm_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; + CMC_CREATE_UNIT(HashBidiMap, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashbidimap *map = hbm_new(943722, 0.6, hbm_fkey, hbm_fval); @@ -87,8 +70,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { }); CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashbidimap *map = hbm_new_custom( - 943722, 0.6, hbm_fkey, hbm_fval, hbm_alloc_node, callbacks); + struct hashbidimap *map = hbm_new_custom(943722, 0.6, hbm_fkey, hbm_fval, hbm_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map->buffer); @@ -123,8 +105,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { CMC_CREATE_TEST(PFX##_clear(), { k_total_free = 0; v_total_free = 0; - struct hashbidimap *map = - hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter); + struct hashbidimap *map = hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); @@ -149,8 +130,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { CMC_CREATE_TEST(PFX##_free(), { k_total_free = 0; v_total_free = 0; - struct hashbidimap *map = - hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter); + struct hashbidimap *map = hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); @@ -178,8 +158,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { }); CMC_CREATE_TEST(customize, { - struct hashbidimap *map = - hbm_new_custom(100, 0.6, hbm_fkey, hbm_fval, NULL, NULL); + struct hashbidimap *map = hbm_new_custom(100, 0.6, hbm_fkey, hbm_fval, NULL, NULL); cmc_assert_not_equals(ptr, NULL, map); @@ -313,8 +292,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { }); CMC_CREATE_TEST(insert[ftab hash calls], { - struct hashbidimap *map = - hbm_new(100, 0.7, hbm_fkey_counter, hbm_fval_counter); + struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey_counter, hbm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); @@ -468,13 +446,10 @@ CMC_CREATE_UNIT(HashBidiMap, true, { }); CMC_CREATE_TEST(remove_by_key[cleanup custom], { - struct hashbidimap *map = - hbm_new_custom(10000, 0.6, hbm_fkey, hbm_fval, - &(struct cmc_alloc_node){ .malloc = malloc, - .calloc = calloc, - .realloc = realloc, - .free = free }, - &(struct cmc_callbacks){ 0 }); + struct hashbidimap *map = hbm_new_custom( + 10000, 0.6, hbm_fkey, hbm_fval, + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }, + &(struct cmc_callbacks){ 0 }); cmc_assert_not_equals(ptr, NULL, map); @@ -493,21 +468,17 @@ CMC_CREATE_UNIT(HashBidiMap, true, { struct hashbidimap_entry *k = map->buffer[i][0]; struct hashbidimap_entry *v = map->buffer[i][1]; - cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && - (v == NULL || v == CMC_ENTRY_DELETED)); + cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED)); } hbm_free(map); }); CMC_CREATE_TEST(remove_by_val[cleanup custom], { - struct hashbidimap *map = - hbm_new_custom(10000, 0.6, hbm_fkey, hbm_fval, - &(struct cmc_alloc_node){ .malloc = malloc, - .calloc = calloc, - .realloc = realloc, - .free = free }, - &(struct cmc_callbacks){ 0 }); + struct hashbidimap *map = hbm_new_custom( + 10000, 0.6, hbm_fkey, hbm_fval, + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }, + &(struct cmc_callbacks){ 0 }); cmc_assert_not_equals(ptr, NULL, map); @@ -526,8 +497,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { struct hashbidimap_entry *k = map->buffer[i][0]; struct hashbidimap_entry *v = map->buffer[i][1]; - cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && - (v == NULL || v == CMC_ENTRY_DELETED)); + cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED)); } hbm_free(map); @@ -601,8 +571,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); // customize - hbm_customize(map, &cmc_alloc_node_default, - &(struct cmc_callbacks){ 0 }); + hbm_customize(map, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 }); cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); // Insert @@ -731,8 +700,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { }); CMC_CREATE_TEST(callbacks, { - struct hashbidimap *map = - hbm_new_custom(100, 0.7, hbm_fkey, hbm_fval, NULL, callbacks); + struct hashbidimap *map = hbm_new_custom(100, 0.7, hbm_fkey, hbm_fval, NULL, callbacks); cmc_assert_not_equals(ptr, NULL, map); cmc_assert_equals(ptr, callbacks, map->callbacks); @@ -835,13 +803,10 @@ int main(void) { int result = HashBidiMap() + HashBidiMapIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | HashBidiMap Suit : %-42s |\n", - result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" | HashBidiMap Suit : %-42s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/hashmap.c b/tests/main/unt/hashmap.c index e2406a5..868da06 100644 --- a/tests/main/unt/hashmap.c +++ b/tests/main/unt/hashmap.c @@ -4,38 +4,25 @@ #include "../src/hashmap.c" -struct hashmap_fkey *hm_fkey = &(struct hashmap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct hashmap_fval *hm_fval = &(struct hashmap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct hashmap_fkey *hm_fkey_counter = &(struct hashmap_fkey){ .cmp = k_c_cmp, - .cpy = k_c_cpy, - .str = k_c_str, - .free = k_c_free, - .hash = k_c_hash, - .pri = k_c_pri }; - -struct hashmap_fval *hm_fval_counter = &(struct hashmap_fval){ .cmp = v_c_cmp, - .cpy = v_c_cpy, - .str = v_c_str, - .free = v_c_free, - .hash = v_c_hash, - .pri = v_c_pri }; - -struct cmc_alloc_node *hm_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +struct hashmap_fkey *hm_fkey = &(struct hashmap_fkey){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct hashmap_fval *hm_fval = &(struct hashmap_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; + +struct hashmap_fkey *hm_fkey_counter = &(struct hashmap_fkey){ + .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri +}; + +struct hashmap_fval *hm_fval_counter = &(struct hashmap_fval){ + .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri +}; + +struct cmc_alloc_node *hm_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; + CMC_CREATE_UNIT(HashMap, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashmap *map = hm_new(943722, 0.6, hm_fkey, hm_fval); @@ -71,8 +58,7 @@ CMC_CREATE_UNIT(HashMap, true, { }); CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashmap *map = hm_new_custom(943722, 0.6, hm_fkey, hm_fval, - hm_alloc_node, callbacks); + struct hashmap *map = hm_new_custom(943722, 0.6, hm_fkey, hm_fval, hm_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map->buffer); @@ -172,8 +158,7 @@ CMC_CREATE_UNIT(HashMap, true, { CMC_CREATE_TEST(PFX##_clear(), { k_total_free = 0; v_total_free = 0; - struct hashmap *map = - hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter); + struct hashmap *map = hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); @@ -205,8 +190,7 @@ CMC_CREATE_UNIT(HashMap, true, { CMC_CREATE_TEST(PFX##_free(), { k_total_free = 0; v_total_free = 0; - struct hashmap *map = - hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter); + struct hashmap *map = hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); @@ -360,8 +344,7 @@ CMC_CREATE_UNIT(HashMap, true, { capacity = hm_capacity(map); // Just to be sure, not part of the test - cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1, - hashcapminus1(0)); + cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1, hashcapminus1(0)); cmc_assert_equals(size_t, capacity - 1, hashcapminus1(0)); cmc_assert(hm_insert(map, 0, 0)); @@ -636,8 +619,7 @@ CMC_CREATE_UNIT(HashMap, true, { }); CMC_CREATE_TEST(PFX##_full(), { - struct hashmap *map = - hm_new(cmc_hashtable_primes[0], 0.99999, hm_fkey, hm_fval); + struct hashmap *map = hm_new(cmc_hashtable_primes[0], 0.99999, hm_fkey, hm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -676,8 +658,7 @@ CMC_CREATE_UNIT(HashMap, true, { cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6), - hm_capacity(map)); + cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6), hm_capacity(map)); hm_free(map); @@ -811,8 +792,7 @@ CMC_CREATE_UNIT(HashMap, true, { }); CMC_CREATE_TEST(callbacks, { - struct hashmap *map = - hm_new_custom(100, 0.6, hm_fkey, hm_fval, NULL, callbacks); + struct hashmap *map = hm_new_custom(100, 0.6, hm_fkey, hm_fval, NULL, callbacks); cmc_assert_not_equals(ptr, NULL, map); @@ -890,13 +870,9 @@ CMC_CREATE_UNIT(HashMap, true, { }); }); -struct hashmap_fkey *hm_fkey_numhash = - &(struct hashmap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = numhash, - .pri = cmc_size_cmp }; +struct hashmap_fkey *hm_fkey_numhash = &(struct hashmap_fkey){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(HashMapIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { @@ -1344,12 +1320,10 @@ int main(void) { int result = HashMap() + HashMapIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | HashMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/hashmultimap.c b/tests/main/unt/hashmultimap.c index 647d804..15df5e2 100644 --- a/tests/main/unt/hashmultimap.c +++ b/tests/main/unt/hashmultimap.c @@ -4,42 +4,25 @@ #include "../src/hashmultimap.c" -struct hashmultimap_fkey *hmm_fkey = - &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct hashmultimap_fval *hmm_fval = - &(struct hashmultimap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct hashmultimap_fkey *hmm_fkey_counter = - &(struct hashmultimap_fkey){ .cmp = k_c_cmp, - .cpy = k_c_cpy, - .str = k_c_str, - .free = k_c_free, - .hash = k_c_hash, - .pri = k_c_pri }; - -struct hashmultimap_fval *hmm_fval_counter = - &(struct hashmultimap_fval){ .cmp = v_c_cmp, - .cpy = v_c_cpy, - .str = v_c_str, - .free = v_c_free, - .hash = v_c_hash, - .pri = v_c_pri }; - -struct cmc_alloc_node *hmm_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +struct hashmultimap_fkey *hmm_fkey = &(struct hashmultimap_fkey){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct hashmultimap_fval *hmm_fval = &(struct hashmultimap_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; + +struct hashmultimap_fkey *hmm_fkey_counter = &(struct hashmultimap_fkey){ + .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri +}; + +struct hashmultimap_fval *hmm_fval_counter = &(struct hashmultimap_fval){ + .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri +}; + +struct cmc_alloc_node *hmm_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; + CMC_CREATE_UNIT(HashMultiMap, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashmultimap *map = hmm_new(943722, 0.6, hmm_fkey, hmm_fval); @@ -87,8 +70,7 @@ CMC_CREATE_UNIT(HashMultiMap, true, { }); CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashmultimap *map = hmm_new_custom( - 943722, 0.6, hmm_fkey, hmm_fval, hmm_alloc_node, callbacks); + struct hashmultimap *map = hmm_new_custom(943722, 0.6, hmm_fkey, hmm_fval, hmm_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, map); cmc_assert_not_equals(ptr, NULL, map->buffer); @@ -123,8 +105,7 @@ CMC_CREATE_UNIT(HashMultiMap, true, { CMC_CREATE_TEST(PFX##_clear(), { k_total_free = 0; v_total_free = 0; - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); @@ -149,8 +130,7 @@ CMC_CREATE_UNIT(HashMultiMap, true, { CMC_CREATE_TEST(PFX##_free(), { k_total_free = 0; v_total_free = 0; - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter); cmc_assert_not_equals(ptr, NULL, map); @@ -380,8 +360,7 @@ CMC_CREATE_UNIT(HashMultiMap, true, { }); CMC_CREATE_TEST(callbacks, { - struct hashmultimap *map = - hmm_new_custom(100, 0.8, hmm_fkey, hmm_fval, NULL, callbacks); + struct hashmultimap *map = hmm_new_custom(100, 0.8, hmm_fkey, hmm_fval, NULL, callbacks); cmc_assert_not_equals(ptr, NULL, map); @@ -481,18 +460,13 @@ CMC_CREATE_UNIT(HashMultiMap, true, { }); }); -struct hashmultimap_fkey *hmm_fkey_numhash = - &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = numhash, - .pri = cmc_size_cmp }; +struct hashmultimap_fkey *hmm_fkey_numhash = &(struct hashmultimap_fkey){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(HashMultiMapIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -526,8 +500,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_end(), { - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -607,8 +580,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -639,8 +611,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -681,8 +652,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { hmm_insert(map, i, i); size_t sum = 0; - for (it = hmm_iter_start(map); !hmm_iter_at_end(&it); - hmm_iter_next(&it)) + for (it = hmm_iter_start(map); !hmm_iter_at_end(&it); hmm_iter_next(&it)) { sum += hmm_iter_value(&it); } @@ -715,8 +685,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { hmm_insert(map, i, i); size_t sum = 0; - for (it = hmm_iter_end(map); !hmm_iter_at_start(&it); - hmm_iter_prev(&it)) + for (it = hmm_iter_end(map); !hmm_iter_at_start(&it); hmm_iter_prev(&it)) { sum += hmm_iter_value(&it); } @@ -737,8 +706,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_advance(), { - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -772,8 +740,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -807,8 +774,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { }); CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct hashmultimap *map = - hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); + struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); cmc_assert_not_equals(ptr, NULL, map); @@ -944,13 +910,10 @@ int main(void) { int result = HashMultiMap() + HashMultiMapIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | HashMultiMap Suit : %-41s |\n", - result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" | HashMultiMap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/hashmultiset.c b/tests/main/unt/hashmultiset.c index cccb6d8..0992033 100644 --- a/tests/main/unt/hashmultiset.c +++ b/tests/main/unt/hashmultiset.c @@ -4,26 +4,17 @@ #include "../src/hashmultiset.c" -struct hashmultiset_fval *hms_fval = - &(struct hashmultiset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct hashmultiset_fval *hms_fval_counter = - &(struct hashmultiset_fval){ .cmp = v_c_cmp, - .cpy = v_c_cpy, - .str = v_c_str, - .free = v_c_free, - .hash = v_c_hash, - .pri = v_c_pri }; - -struct cmc_alloc_node *hms_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +struct hashmultiset_fval *hms_fval = &(struct hashmultiset_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct hashmultiset_fval *hms_fval_counter = &(struct hashmultiset_fval){ + .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri +}; + +struct cmc_alloc_node *hms_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; + CMC_CREATE_UNIT(HashMultiSet, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashmultiset *set = hms_new(943722, 0.6, hms_fval); @@ -55,8 +46,7 @@ CMC_CREATE_UNIT(HashMultiSet, true, { }); CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashmultiset *set = - hms_new_custom(943722, 0.6, hms_fval, hms_alloc_node, callbacks); + struct hashmultiset *set = hms_new_custom(943722, 0.6, hms_fval, hms_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, set); cmc_assert_not_equals(ptr, NULL, set->buffer); @@ -336,8 +326,7 @@ CMC_CREATE_UNIT(HashMultiSet, true, { }); CMC_CREATE_TEST(callbacks, { - struct hashmultiset *set = - hms_new_custom(100, 0.8, hms_fval, NULL, callbacks); + struct hashmultiset *set = hms_new_custom(100, 0.8, hms_fval, NULL, callbacks); cmc_assert_not_equals(ptr, NULL, set); @@ -425,13 +414,9 @@ CMC_CREATE_UNIT(HashMultiSet, true, { }); }); -struct hashmultiset_fval *hms_fval_numhash = - &(struct hashmultiset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = numhash, - .pri = cmc_size_cmp }; +struct hashmultiset_fval *hms_fval_numhash = &(struct hashmultiset_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(HashMultiSetIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { @@ -621,8 +606,7 @@ CMC_CREATE_UNIT(HashMultiSetIter, true, { hms_insert(set, i); size_t sum = 0; - for (it = hms_iter_start(set); !hms_iter_at_end(&it); - hms_iter_next(&it)) + for (it = hms_iter_start(set); !hms_iter_at_end(&it); hms_iter_next(&it)) { sum += hms_iter_value(&it); } @@ -655,8 +639,7 @@ CMC_CREATE_UNIT(HashMultiSetIter, true, { hms_insert(set, i); size_t sum = 0; - for (it = hms_iter_end(set); !hms_iter_at_start(&it); - hms_iter_prev(&it)) + for (it = hms_iter_end(set); !hms_iter_at_start(&it); hms_iter_prev(&it)) { sum += hms_iter_value(&it); } @@ -864,13 +847,10 @@ int main(void) { int result = HashMultiSet() + HashMultiSetIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | HashMultiSet Suit : %-41s |\n", - result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" | HashMultiSet Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/hashset.c b/tests/main/unt/hashset.c index df242d3..78e79a2 100644 --- a/tests/main/unt/hashset.c +++ b/tests/main/unt/hashset.c @@ -4,24 +4,17 @@ #include "../src/hashset.c" -struct hashset_fval *hs_fval = &(struct hashset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct hashset_fval *hs_fval_counter = &(struct hashset_fval){ .cmp = v_c_cmp, - .cpy = v_c_cpy, - .str = v_c_str, - .free = v_c_free, - .hash = v_c_hash, - .pri = v_c_pri }; - -struct cmc_alloc_node *hs_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +struct hashset_fval *hs_fval = &(struct hashset_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct hashset_fval *hs_fval_counter = &(struct hashset_fval){ + .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri +}; + +struct cmc_alloc_node *hs_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; + CMC_CREATE_UNIT(HashSet, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashset *set = hs_new(943722, 0.6, hs_fval); @@ -53,8 +46,7 @@ CMC_CREATE_UNIT(HashSet, true, { }); CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashset *set = - hs_new_custom(943722, 0.6, hs_fval, hs_alloc_node, callbacks); + struct hashset *set = hs_new_custom(943722, 0.6, hs_fval, hs_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, set); cmc_assert_not_equals(ptr, NULL, set->buffer); @@ -165,8 +157,7 @@ CMC_CREATE_UNIT(HashSet, true, { cmc_assert(hs_insert(set, capacity - 1)); cmc_assert(hs_insert(set, capacity)); - cmc_assert_equals(size_t, capacity - 1, - set->buffer[capacity - 1].value); + cmc_assert_equals(size_t, capacity - 1, set->buffer[capacity - 1].value); cmc_assert_equals(size_t, capacity, set->buffer[0].value); hs_fval->hash = cmc_size_hash; @@ -206,8 +197,7 @@ CMC_CREATE_UNIT(HashSet, true, { size_t capacity = hs_capacity(set); // Just to be sure, not part of the test - cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1, - hashcapminus1(0)); + cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1, hashcapminus1(0)); cmc_assert_equals(size_t, capacity - 1, hashcapminus1(0)); cmc_assert(hs_insert(set, 0)); @@ -451,8 +441,7 @@ CMC_CREATE_UNIT(HashSet, true, { cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6), - hs_capacity(set)); + cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6), hs_capacity(set)); hs_free(set); }); @@ -625,13 +614,9 @@ CMC_CREATE_UNIT(HashSet, true, { }); }); -struct hashset_fval *hs_fval_numhash = - &(struct hashset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = numhash, - .pri = cmc_size_cmp }; +struct hashset_fval *hs_fval_numhash = &(struct hashset_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(HashSetIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { @@ -1042,12 +1027,10 @@ int main(void) { int result = HashSet() + HashSetIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | HashSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/heap.c b/tests/main/unt/heap.c index 0bd09ff..dcf7e9e 100644 --- a/tests/main/unt/heap.c +++ b/tests/main/unt/heap.c @@ -4,12 +4,9 @@ #include "../src/heap.c" -struct heap_fval *h_fval = &(struct heap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct heap_fval *h_fval = &(struct heap_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(Heap, true, { CMC_CREATE_TEST(new, { @@ -222,8 +219,7 @@ CMC_CREATE_UNIT(Heap, true, { }); CMC_CREATE_TEST(callbacks, { - struct heap *h = - h_new_custom(100, CMC_MAX_HEAP, h_fval, NULL, callbacks); + struct heap *h = h_new_custom(100, CMC_MAX_HEAP, h_fval, NULL, callbacks); cmc_assert_not_equals(ptr, NULL, h); @@ -720,12 +716,10 @@ int main(void) { int result = Heap() + HeapIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | Heap Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/intervalheap.c b/tests/main/unt/intervalheap.c index 3a1e9b0..9d3d06c 100644 --- a/tests/main/unt/intervalheap.c +++ b/tests/main/unt/intervalheap.c @@ -4,26 +4,17 @@ #include "../src/intervalheap.c" -struct intervalheap_fval *ih_fval = - &(struct intervalheap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; - -struct intervalheap_fval *ih_fval_counter = - &(struct intervalheap_fval){ .cmp = v_c_cmp, - .cpy = v_c_cpy, - .str = v_c_str, - .free = v_c_free, - .hash = v_c_hash, - .pri = v_c_pri }; - -struct cmc_alloc_node *ih_alloc_node = &(struct cmc_alloc_node){ - .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free +struct intervalheap_fval *ih_fval = &(struct intervalheap_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; +struct intervalheap_fval *ih_fval_counter = &(struct intervalheap_fval){ + .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri +}; + +struct cmc_alloc_node *ih_alloc_node = + &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; + CMC_CREATE_UNIT(IntervalHeap, true, { CMC_CREATE_TEST(PFX##_new(), { struct intervalheap *ih = ih_new(1000000, ih_fval); @@ -72,8 +63,7 @@ CMC_CREATE_UNIT(IntervalHeap, true, { }); CMC_CREATE_TEST(PFX##_new_custom(), { - struct intervalheap *ih = - ih_new_custom(1000000, ih_fval, ih_alloc_node, callbacks); + struct intervalheap *ih = ih_new_custom(1000000, ih_fval, ih_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, ih); cmc_assert_not_equals(ptr, NULL, ih->buffer); @@ -1044,13 +1034,10 @@ int main(void) { int result = IntervalHeap() + IntervalHeapIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | IntervalHeap Suit : %-41s |\n", - result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" | IntervalHeap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/linkedlist.c b/tests/main/unt/linkedlist.c index 8962a63..cc4989e 100644 --- a/tests/main/unt/linkedlist.c +++ b/tests/main/unt/linkedlist.c @@ -4,13 +4,9 @@ #include "../src/linkedlist.c" -struct linkedlist_fval *ll_fval = - &(struct linkedlist_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct linkedlist_fval *ll_fval = &(struct linkedlist_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(LinkedList, true, { CMC_CREATE_TEST(new, { @@ -804,12 +800,10 @@ int main(void) { int result = LinkedList() + LinkedListIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | LinkedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/list.c b/tests/main/unt/list.c index 6beae16..2369b57 100644 --- a/tests/main/unt/list.c +++ b/tests/main/unt/list.c @@ -4,12 +4,9 @@ #include "../src/list.c" -struct list_fval *l_fval = &(struct list_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct list_fval *l_fval = &(struct list_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(List, true, { CMC_CREATE_TEST(new, { @@ -1070,12 +1067,10 @@ int main(void) { int result = List() + ListIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | List Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/queue.c b/tests/main/unt/queue.c index 4fd0e3f..990b386 100644 --- a/tests/main/unt/queue.c +++ b/tests/main/unt/queue.c @@ -4,12 +4,9 @@ #include "../src/queue.c" -struct queue_fval *q_fval = &(struct queue_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct queue_fval *q_fval = &(struct queue_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(Queue, true, { CMC_CREATE_TEST(new, { @@ -78,8 +75,7 @@ CMC_CREATE_UNIT(Queue, true, { } size_t sum = 0; - for (size_t i = q->front, j = 0; j < q->count; - i = (i + 1) % q->capacity, j++) + for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++) sum += q->buffer[i]; cmc_assert_equals(size_t, 1200, q_count(q)); @@ -112,8 +108,7 @@ CMC_CREATE_UNIT(Queue, true, { size_t sum = 0; - for (size_t i = q->front, j = 0; j < q->count; - i = (i + 1) % q->capacity, j++) + for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++) { sum += q->buffer[i]; } @@ -154,8 +149,7 @@ CMC_CREATE_UNIT(Queue, true, { size_t sum = 0; - for (size_t i = q->front, j = 0; j < q->count; - i = (i + 1) % q->capacity, j++) + for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++) { sum += q->buffer[i]; } @@ -326,8 +320,7 @@ CMC_CREATE_UNIT(Queue, true, { size_t sum = 0; - for (size_t i = q->front, j = 0; j < q->count; - i = (i + 1) % q->capacity, j++) + for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++) { sum += q->buffer[i]; } @@ -960,12 +953,10 @@ int main(void) { int result = Queue() + QueueIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | Queue Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/sortedlist.c b/tests/main/unt/sortedlist.c index 58b967e..d21cca6 100644 --- a/tests/main/unt/sortedlist.c +++ b/tests/main/unt/sortedlist.c @@ -4,13 +4,9 @@ #include "../src/sortedlist.c" -struct sortedlist_fval *sl_fval = - &(struct sortedlist_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct sortedlist_fval *sl_fval = &(struct sortedlist_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(SortedList, true, { CMC_CREATE_TEST(new, { @@ -66,8 +62,7 @@ CMC_CREATE_UNIT(SortedList, true, { sl_sort(sl); cmc_assert_equals(size_t, 50, sl_count(sl)); - cmc_assert_array_sorted_any(size_t, sl->buffer, cmc_size_cmp, 0, - sl->count - 1); + cmc_assert_array_sorted_any(size_t, sl->buffer, cmc_size_cmp, 0, sl->count - 1); sl_free(sl); }); @@ -705,12 +700,10 @@ int main(void) { int result = SortedList() + SortedListIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | SortedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/stack.c b/tests/main/unt/stack.c index 298773a..17f78e9 100644 --- a/tests/main/unt/stack.c +++ b/tests/main/unt/stack.c @@ -4,12 +4,9 @@ #include "../src/stack.c" -struct stack_fval *s_fval = &(struct stack_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct stack_fval *s_fval = &(struct stack_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(Stack, true, { CMC_CREATE_TEST(new, { @@ -838,12 +835,10 @@ int main(void) { int result = Stack() + StackIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | Stack Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/treemap.c b/tests/main/unt/treemap.c index 9ce8b79..379407c 100644 --- a/tests/main/unt/treemap.c +++ b/tests/main/unt/treemap.c @@ -4,19 +4,13 @@ #include "../src/treemap.c" -struct treemap_fkey *tm_fkey = &(struct treemap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct treemap_fkey *tm_fkey = &(struct treemap_fkey){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; -struct treemap_fval *tm_fval = &(struct treemap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct treemap_fval *tm_fval = &(struct treemap_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(TreeMap, true, { CMC_CREATE_TEST(new, { @@ -659,12 +653,10 @@ int main(void) { int result = TreeMap() + TreeMapIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | TreeMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/treeset.c b/tests/main/unt/treeset.c index eef1667..cce4a14 100644 --- a/tests/main/unt/treeset.c +++ b/tests/main/unt/treeset.c @@ -4,12 +4,9 @@ #include "../src/treeset.c" -struct treeset_fval *ts_fval = &(struct treeset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }; +struct treeset_fval *ts_fval = &(struct treeset_fval){ + .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp +}; CMC_CREATE_UNIT(TreeSet, true, { CMC_CREATE_TEST(new, { @@ -574,12 +571,10 @@ int main(void) { int result = TreeSet() + TreeSetIter(); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n"); printf(" | TreeSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf( - " +---------------------------------------------------------------+"); + printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; diff --git a/tests/main/unt/utl.c b/tests/main/unt/utl.c index 44376a7..591157e 100644 --- a/tests/main/unt/utl.c +++ b/tests/main/unt/utl.c @@ -2,15 +2,6 @@ #ifndef CMC_UNIT_TEST_UTL__ #define CMC_UNIT_TEST_UTL__ -/** - * TEMPORARY - */ -struct cmc_string -{ - char s[400]; -}; -static const size_t cmc_string_len = 400; - #include #include #include @@ -163,11 +154,10 @@ void callback_resize(void) total_resize++; } -struct cmc_callbacks *callbacks = - &(struct cmc_callbacks){ .create = callback_create, - .read = callback_read, - .update = callback_update, - .delete = callback_delete, - .resize = callback_resize }; +struct cmc_callbacks *callbacks = &(struct cmc_callbacks){ .create = callback_create, + .read = callback_read, + .update = callback_update, + .delete = callback_delete, + .resize = callback_resize }; #endif /* CMC_UNIT_TEST_UTL__ */ From e85bc722037932198c27f94d64e412f778c1cc54 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 5 Jun 2020 10:47:57 -0300 Subject: [PATCH 23/51] Moving more stuff to EXT and fixing typo --- src/cmc/hashmultiset.h | 2 +- src/cmc/queue.h | 274 +-------------------------------- src/ext/cmc/queue.h | 329 ++++++++++++++++++++++++++++++++++++++++ src/macro_collections.h | 1 + tests/to_string.c | 11 ++ 5 files changed, 343 insertions(+), 274 deletions(-) create mode 100644 src/ext/cmc/queue.h diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index 3ebb891..64553e8 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -171,7 +171,7 @@ \ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ - return CMC_(PFX, _new_custom)(capaccapacity, load, f_val, NULL, NULL); \ + return CMC_(PFX, _new_custom)(capacity, load, f_val, NULL, NULL); \ } \ \ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ diff --git a/src/cmc/queue.h b/src/cmc/queue.h index dda6d1f..e2cd5ad 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -48,22 +48,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * Queue specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_queue = "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 Queue implementation */ @@ -179,29 +163,7 @@ static const char *cmc_cmc_string_fmt_queue = "struct %s<%s> " /* Collection Utility */ \ bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_); \ - bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _queue_); \ - bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr); \ -\ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_); /* ------------------------------------------------------------------------- * Source @@ -508,240 +470,6 @@ static const char *cmc_cmc_string_fmt_queue = "struct %s<%s> " } \ \ return true; \ - } \ -\ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _queue_) \ - { \ - struct cmc_string str; \ - struct SNAME *q_ = _queue_; \ -\ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_queue, #SNAME, #V, q_, q_->buffer, q_->capacity, \ - q_->count, q_->front, q_->back, q_->flag, q_->f_val, q_->alloc, q_->callbacks); \ -\ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) \ - return false; \ -\ - i = (i + 1) % _queue_->capacity; \ - } \ -\ - return true; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->front; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - if (iter.target->back == 0) \ - iter.cursor = iter.target->capacity - 1; \ - else \ - iter.cursor = iter.target->back - 1; \ -\ - iter.index = iter.target->count - 1; \ - } \ - else \ - { \ - iter.cursor = 0; \ - iter.index = 0; \ - } \ -\ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - if (iter->target->back == 0) \ - iter->cursor = iter->target->capacity - 1; \ - else \ - iter->cursor = iter->target->back - 1; \ -\ - iter->index = iter->target->count - 1; \ -\ - iter->start = false; \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \ - iter->index--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->index += steps; \ - iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->index -= steps; \ -\ - /* Prevent underflow */ \ - if (iter->cursor < steps) \ - iter->cursor += iter->target->capacity; \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->target->buffer[iter->cursor]); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ } #endif /* CMC_CMC_QUEUE_H */ diff --git a/src/ext/cmc/queue.h b/src/ext/cmc/queue.h new file mode 100644 index 0000000..655e895 --- /dev/null +++ b/src/ext/cmc/queue.h @@ -0,0 +1,329 @@ +/** + * ext/cmc/queue.h + * + * Creation Date: 05/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_QUEUE_H +#define CMC_EXT_CMC_QUEUE_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC Queue. + */ +#define CMC_EXT_CMC_QUEUE_PARTS ITER, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_QUEUE_ITER(PARAMS) \ + CMC_EXT_CMC_QUEUE_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_QUEUE_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_QUEUE_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_QUEUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_QUEUE_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_QUEUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_QUEUE_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_QUEUE_ITER_SOURCE_(PFX, SNAME, V) \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->front; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + if (iter.target->back == 0) \ + iter.cursor = iter.target->capacity - 1; \ + else \ + iter.cursor = iter.target->back - 1; \ +\ + iter.index = iter.target->count - 1; \ + } \ + else \ + { \ + iter.cursor = 0; \ + iter.index = 0; \ + } \ +\ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->front; \ + iter->index = 0; \ + iter->start = true; \ + iter->end = false; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + if (iter->target->back == 0) \ + iter->cursor = iter->target->capacity - 1; \ + else \ + iter->cursor = iter->target->back - 1; \ +\ + iter->index = iter->target->count - 1; \ +\ + iter->start = false; \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ + iter->index++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \ + iter->index--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->index + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->index += steps; \ + iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->index == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->index -= steps; \ +\ + /* Prevent underflow */ \ + if (iter->cursor < steps) \ + iter->cursor += iter->target->capacity; \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->target->buffer[iter->cursor]); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_QUEUE_STR(PARAMS) \ + CMC_EXT_CMC_QUEUE_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_QUEUE_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_QUEUE_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_QUEUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_QUEUE_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_QUEUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_QUEUE_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _queue_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr, const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_QUEUE_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _queue_, FILE * fptr) \ + { \ + struct SNAME *q_ = _queue_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "front:%" PRIuMAX ", " \ + "back:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), q_, q_->buffer, q_->capacity, q_->count, \ + q_->front, q_->back, q_->flag, q_->f_val, q_->alloc, CMC_CALLBACKS_GET(q_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ + { \ + if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) \ + return false; \ +\ + i = (i + 1) % _queue_->capacity; \ +\ + if (j + 1 < _queue_->count) \ + fprintf(fptr, "%s", separator); \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ + } + +#endif /* CMC_EXT_CMC_QUEUE_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 12d0b92..d22bcef 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -62,6 +62,7 @@ #include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */ #include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */ #include "ext/cmc/list.h" /* Added in 04/06/2020 */ +#include "ext/cmc/queue.h" /* Added in 05/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/to_string.c b/tests/to_string.c index 72dd3fd..6d906da 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -12,6 +12,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h, heap, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih, intervalheap, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q, queue, , , int)) struct { @@ -39,6 +40,7 @@ int main(void) struct intervalheap *ih = ih_new(100, (struct intervalheap_fval *)&int_ftab); struct linkedlist *ll = ll_new((struct linkedlist_fval *)&int_ftab); struct list *l = l_new(100, (struct list_fval *)&int_ftab); + struct queue *q = q_new(100, (struct queue_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -58,6 +60,8 @@ int main(void) ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); l_to_string(l, stdout); l_print(l, stdout, "\n[ ", ", ", " ]\n"); + q_to_string(q, stdout); + q_print(q, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -70,6 +74,7 @@ int main(void) ih_insert(ih, 0); ll_push_back(ll, 0); l_push_back(l, 0); + q_enqueue(q, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -89,6 +94,8 @@ int main(void) ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); l_to_string(l, stdout); l_print(l, stdout, "\n[ ", ", ", " ]\n"); + q_to_string(q, stdout); + q_print(q, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -101,6 +108,7 @@ int main(void) ih_insert(ih, i); ll_push_back(ll, i); l_push_back(l, i); + q_enqueue(q, i); } fprintf(stdout, "\n"); @@ -123,6 +131,8 @@ int main(void) ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); l_to_string(l, stdout); l_print(l, stdout, "\n[ ", ", ", " ]\n"); + q_to_string(q, stdout); + q_print(q, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hm_free(hm); @@ -133,6 +143,7 @@ int main(void) ih_free(ih); ll_free(ll); l_free(l); + q_free(q); } // clang-format on From 59a1e2a682a70bc4f954ab7afe994b98280b570b Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 5 Jun 2020 15:46:52 -0300 Subject: [PATCH 24/51] Somewhat working optional callbacks --- src/cmc/bitset.h | 6 +- src/cmc/deque.h | 4 ++ src/cmc/hashbidimap.h | 120 +++++--------------------------------- src/cmc/hashmap.h | 31 +++++----- src/cmc/hashmultimap.h | 37 +++++------- src/cmc/hashmultiset.h | 34 +++++------ src/cmc/hashset.h | 22 ++++--- src/cmc/heap.h | 19 +++--- src/cmc/intervalheap.h | 33 +++++------ src/cmc/linkedlist.h | 37 +++++------- src/cmc/list.h | 43 ++++++-------- src/cmc/queue.h | 19 +++--- src/cmc/sortedlist.h | 28 ++++----- src/cmc/stack.h | 19 +++--- src/cmc/treemap.h | 28 ++++----- src/cmc/treeset.h | 19 +++--- src/cor/callbacks.h | 4 +- src/cor/core.h | 10 ++++ src/ext/cmc/deque.h | 2 + src/ext/cmc/hashbidimap.h | 86 ++++++++++++++++++++++++++- src/ext/cmc/hashmap.h | 2 + src/ext/cmc/list.h | 17 ++---- src/macro_collections.h | 1 + tests/to_string.c | 13 +++++ 24 files changed, 304 insertions(+), 330 deletions(-) diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index 9fa4237..25e4915 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -204,8 +204,10 @@ static const char *cmc_cmc_string_fmt_bitset = "struct %s " } \ \ struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ + struct CMC_CALLBACKS_NAME * CMC_UNUSED(callbacks)) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ struct SNAME _bitset_ = { 0 }; \ \ if (n_bits < 1) \ @@ -243,6 +245,8 @@ static const char *cmc_cmc_string_fmt_bitset = "struct %s " void CMC_(PFX, _customize)(struct SNAME * _bitset_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _bitset_->alloc = &cmc_alloc_node_default; \ else \ diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 3f7122f..74c3956 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -155,6 +155,8 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity < 1) \ return NULL; \ \ @@ -229,6 +231,8 @@ void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _deque_->alloc = &cmc_alloc_node_default; \ else \ diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index d605142..e5ef175 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -36,22 +36,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/hashtable.h" -/* ------------------------------------------------------------------------- - * HashBidimap Specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_hashbidimap = "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 HashBidiMap implementation */ @@ -235,8 +219,6 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ \ /* Iterator Functions */ \ /* Iterator Allocation and Deallocation */ \ @@ -280,52 +262,15 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ - struct CMC_ALLOC_NODE_NAME *alloc = &cmc_alloc_node_default; \ -\ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ -\ - if (!f_key || !f_val) \ - return NULL; \ -\ - size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ -\ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_map_) \ - return NULL; \ -\ - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ -\ - if (!_map_->buffer) \ - { \ - alloc->free(_map_->buffer); \ - alloc->free(_map_); \ - return NULL; \ - } \ -\ - _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; \ - CMC_CALLBACKS_ASSIGN(_map_, NULL); \ - _map_->it_start = CMC_(PFX, _impl_it_start); \ - _map_->it_end = CMC_(PFX, _impl_it_end); \ -\ - return _map_; \ + return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL);\ } \ \ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ \ @@ -405,6 +350,8 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ else \ @@ -452,8 +399,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " _map_->count++; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_map_, create); \ \ return true; \ } \ @@ -516,8 +462,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_map_, update); \ \ return true; \ } \ @@ -581,8 +526,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_map_, update); \ \ return true; \ } \ @@ -627,8 +571,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " _map_->count--; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_map_, delete); \ \ return true; \ } \ @@ -673,8 +616,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " _map_->count--; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_map_, delete); \ \ return true; \ } \ @@ -691,8 +633,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return (*entry)->key; \ } \ @@ -709,8 +650,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return (*entry)->value; \ } \ @@ -721,8 +661,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ bool result = CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return result; \ } \ @@ -733,8 +672,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ bool result = CMC_(PFX, _impl_get_entry_by_val)(_map_, val) != NULL; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return result; \ } \ @@ -857,8 +795,7 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ success: \ \ - if (_map_->callbacks && _map_->callbacks->resize) \ - _map_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_map_, resize); \ \ return true; \ } \ @@ -951,33 +888,6 @@ static const char *cmc_cmc_string_fmt_hashbidimap = "struct %s<%s, %s> " \ return true; \ } \ -\ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ -\ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_hashbidimap, #SNAME, #K, #V, m_, m_->buffer, \ - m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ -\ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[i][0]; \ -\ - if (target && target != CMC_ENTRY_DELETED) \ - { \ - if (!_map_->f_key->str(fptr, target->key) || !_map_->f_val->str(fptr, target->value)) \ - return false; \ - } \ - } \ -\ - return true; \ - } \ \ struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target) \ { \ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 3ac5ae1..2eb00a9 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -194,6 +194,8 @@ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ \ @@ -283,6 +285,8 @@ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ else \ @@ -356,8 +360,7 @@ _map_->count++; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_map_, create); \ \ return true; \ } \ @@ -385,8 +388,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_map_, update); \ \ return true; \ } \ @@ -418,8 +420,7 @@ _map_->count--; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_map_, delete); \ \ return true; \ } \ @@ -463,8 +464,7 @@ if (value) \ *value = max_val; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return true; \ } \ @@ -508,8 +508,7 @@ if (value) \ *value = min_val; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return true; \ } \ @@ -532,8 +531,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return entry->value; \ } \ @@ -556,8 +554,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return &(entry->value); \ } \ @@ -568,8 +565,7 @@ \ bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return result; \ } \ @@ -678,8 +674,7 @@ \ success: \ \ - if (_map_->callbacks && _map_->callbacks->resize) \ - _map_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_map_, resize); \ \ return true; \ } \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index 38dea54..ac79010 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -223,6 +223,8 @@ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity == 0 || load <= 0) \ return NULL; \ \ @@ -337,6 +339,8 @@ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ else \ @@ -376,8 +380,7 @@ _map_->count++; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_map_, create); \ \ return true; \ } \ @@ -405,8 +408,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_map_, update); \ \ return true; \ } \ @@ -466,8 +468,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_map_, update); \ \ return index; \ } \ @@ -550,8 +551,7 @@ _map_->count--; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_map_, delete); \ \ return true; \ } \ @@ -642,8 +642,7 @@ _map_->count -= index; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_map_, delete); \ \ return index; \ } \ @@ -687,8 +686,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return true; \ } \ @@ -732,8 +730,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return true; \ } \ @@ -756,8 +753,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return entry->value; \ } \ @@ -780,8 +776,7 @@ \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return &(entry->value); \ } \ @@ -792,8 +787,7 @@ \ bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return result; \ } \ @@ -906,8 +900,7 @@ \ success: \ \ - if (_map_->callbacks && _map_->callbacks->resize) \ - _map_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_map_, resize); \ \ return true; \ } \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index 64553e8..673613b 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -177,6 +177,8 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ \ @@ -260,6 +262,8 @@ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ else \ @@ -288,8 +292,7 @@ _set_->cardinality++; \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->create) \ - _set_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_set_, create); \ \ return true; \ } \ @@ -320,8 +323,7 @@ \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->create) \ - _set_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_set_, create); \ \ return true; \ } \ @@ -366,8 +368,7 @@ \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->update) \ - _set_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_set_, update); \ \ return true; \ } \ @@ -403,8 +404,7 @@ _set_->cardinality--; \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->delete) \ - _set_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_set_, delete); \ \ return true; \ } \ @@ -436,8 +436,7 @@ _set_->cardinality -= removed; \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->delete) \ - _set_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_set_, delete); \ \ return removed; \ } \ @@ -470,8 +469,7 @@ \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return true; \ } \ @@ -504,8 +502,7 @@ \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return true; \ } \ @@ -516,8 +513,7 @@ \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ if (!entry) \ return 0; \ @@ -531,8 +527,7 @@ \ bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return result; \ } \ @@ -640,8 +635,7 @@ \ success: \ \ - if (_set_->callbacks && _set_->callbacks->resize) \ - _set_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_set_, resize); \ \ return true; \ } \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index d8d9a3c..7acb6be 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -156,6 +156,8 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ \ @@ -238,6 +240,8 @@ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ else \ @@ -306,8 +310,7 @@ _set_->count++; \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->create) \ - _set_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_set_, create); \ \ return true; \ } \ @@ -335,8 +338,7 @@ _set_->count--; \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->delete) \ - _set_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_set_, delete); \ \ return true; \ } \ @@ -369,8 +371,7 @@ \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return true; \ } \ @@ -403,8 +404,7 @@ \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return true; \ } \ @@ -415,8 +415,7 @@ \ bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return result; \ } \ @@ -522,8 +521,7 @@ \ success: \ \ - if (_set_->callbacks && _set_->callbacks->resize) \ - _set_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_set_, resize); \ \ return true; \ } \ diff --git a/src/cmc/heap.h b/src/cmc/heap.h index adee37f..d0d52d2 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -152,6 +152,8 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity < 1) \ return NULL; \ \ @@ -221,6 +223,8 @@ void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _heap_->alloc = &cmc_alloc_node_default; \ else \ @@ -248,8 +252,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->create) \ - _heap_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_heap_, create); \ \ return true; \ } \ @@ -271,8 +274,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->delete) \ - _heap_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_heap_, delete); \ \ return true; \ } \ @@ -287,8 +289,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_heap_, read); \ \ return _heap_->buffer[0]; \ } \ @@ -308,8 +309,7 @@ } \ } \ \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_heap_, read); \ \ return result; \ } \ @@ -367,8 +367,7 @@ \ success: \ \ - if (_heap_->callbacks && _heap_->callbacks->resize) \ - _heap_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_heap_, resize); \ \ return true; \ } \ diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index f141a6b..ad04db3 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -124,7 +124,7 @@ int CMC_(PFX, _flag)(struct SNAME * _heap_); \ /* Collection Utility */ \ bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \ bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); /* ------------------------------------------------------------------------- @@ -146,6 +146,8 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity == 0 || capacity == UINTMAX_MAX) \ return NULL; \ \ @@ -216,6 +218,8 @@ void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _heap_->alloc = &cmc_alloc_node_default; \ else \ @@ -277,8 +281,7 @@ /* else no float up required */ \ } \ \ - if (_heap_->callbacks && _heap_->callbacks->create) \ - _heap_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_heap_, create); \ \ return true; \ } \ @@ -330,8 +333,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->delete) \ - _heap_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_heap_, delete); \ \ return true; \ } \ @@ -383,8 +385,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->delete) \ - _heap_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_heap_, delete); \ \ return true; \ } \ @@ -420,8 +421,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->update) \ - _heap_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_heap_, update); \ \ return true; \ } \ @@ -457,8 +457,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->update) \ - _heap_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_heap_, update); \ \ return true; \ } \ @@ -473,8 +472,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_heap_, read); \ \ /* If there is only one element, then the maximum element is the */ \ /* same as the one in the MinHeap */ \ @@ -494,8 +492,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_heap_, read); \ \ return _heap_->buffer[0][0]; \ } \ @@ -515,8 +512,7 @@ } \ } \ \ - if (_heap_->callbacks && _heap_->callbacks->read) \ - _heap_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_heap_, read); \ \ return result; \ } \ @@ -587,8 +583,7 @@ \ _heap_->flag = CMC_FLAG_OK; \ \ - if (_heap_->callbacks && _heap_->callbacks->resize) \ - _heap_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_heap_, resize); \ \ return true; \ } \ diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index 044a737..3e223f6 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -158,6 +158,8 @@ struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!f_val) \ return NULL; \ \ @@ -214,6 +216,8 @@ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ else \ @@ -246,8 +250,7 @@ _list_->count++; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -284,8 +287,7 @@ _list_->count++; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -312,8 +314,7 @@ _list_->count++; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -339,8 +340,7 @@ _list_->count--; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return true; \ } \ @@ -381,8 +381,7 @@ _list_->count--; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return true; \ } \ @@ -408,8 +407,7 @@ _list_->count--; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return true; \ } \ @@ -424,8 +422,7 @@ \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return _list_->head->value; \ } \ @@ -449,8 +446,7 @@ if (scan == NULL) \ return (V){ 0 }; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return scan->value; \ } \ @@ -474,8 +470,7 @@ if (scan == NULL) \ return NULL; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return &(scan->value); \ } \ @@ -490,8 +485,7 @@ \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return _list_->tail->value; \ } \ @@ -515,8 +509,7 @@ scan = scan->next; \ } \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return result; \ } \ diff --git a/src/cmc/list.h b/src/cmc/list.h index 5ba990a..0a53453 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -165,6 +165,8 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity < 1) \ return NULL; \ \ @@ -226,6 +228,8 @@ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ else \ @@ -254,8 +258,7 @@ _list_->count++; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -280,8 +283,7 @@ _list_->count++; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -297,8 +299,7 @@ _list_->buffer[_list_->count++] = value; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -316,8 +317,7 @@ _list_->buffer[--_list_->count] = (V){ 0 }; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return true; \ } \ @@ -341,8 +341,7 @@ _list_->buffer[--_list_->count] = (V){ 0 }; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return true; \ } \ @@ -355,8 +354,7 @@ _list_->buffer[--_list_->count] = (V){ 0 }; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return true; \ } \ @@ -371,8 +369,7 @@ \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return _list_->buffer[0]; \ } \ @@ -393,8 +390,7 @@ \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return _list_->buffer[index]; \ } \ @@ -415,8 +411,7 @@ \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return &(_list_->buffer[index]); \ } \ @@ -431,8 +426,7 @@ \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return _list_->buffer[_list_->count - 1]; \ } \ @@ -466,8 +460,7 @@ } \ } \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return result; \ } \ @@ -487,8 +480,7 @@ } \ } \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return result; \ } \ @@ -549,8 +541,7 @@ _list_->buffer = new_buffer; \ _list_->capacity = capacity; \ \ - if (_list_->callbacks && _list_->callbacks->resize) \ - _list_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_list_, resize); \ \ return true; \ } \ diff --git a/src/cmc/queue.h b/src/cmc/queue.h index e2cd5ad..652b715 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -181,6 +181,8 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity < 1) \ return NULL; \ \ @@ -254,6 +256,8 @@ void CMC_(PFX, _customize)(struct SNAME * _queue_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _queue_->alloc = &cmc_alloc_node_default; \ else \ @@ -278,8 +282,7 @@ _queue_->count++; \ _queue_->flag = CMC_FLAG_OK; \ \ - if (_queue_->callbacks && _queue_->callbacks->create) \ - _queue_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_queue_, create); \ \ return true; \ } \ @@ -298,8 +301,7 @@ _queue_->count--; \ _queue_->flag = CMC_FLAG_OK; \ \ - if (_queue_->callbacks && _queue_->callbacks->delete) \ - _queue_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_queue_, delete); \ \ return true; \ } \ @@ -314,8 +316,7 @@ \ _queue_->flag = CMC_FLAG_OK; \ \ - if (_queue_->callbacks && _queue_->callbacks->read) \ - _queue_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_queue_, read); \ \ return _queue_->buffer[_queue_->front]; \ } \ @@ -337,8 +338,7 @@ i = (i + 1) % _queue_->capacity; \ } \ \ - if (_queue_->callbacks && _queue_->callbacks->read) \ - _queue_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_queue_, read); \ \ return result; \ } \ @@ -405,8 +405,7 @@ \ _queue_->flag = CMC_FLAG_OK; \ \ - if (_queue_->callbacks && _queue_->callbacks->resize) \ - _queue_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_queue_, resize); \ \ return true; \ } \ diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h index 076e23b..847f047 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc/sortedlist.h @@ -197,6 +197,8 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity < 1) \ return NULL; \ \ @@ -256,6 +258,8 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ else \ @@ -279,8 +283,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " _list_->is_sorted = false; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -305,8 +308,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return true; \ } \ @@ -323,8 +325,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return _list_->buffer[_list_->count - 1]; \ } \ @@ -341,8 +342,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return _list_->buffer[0]; \ } \ @@ -365,8 +365,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return _list_->buffer[index]; \ } \ @@ -377,8 +376,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " \ CMC_(PFX, _sort)(_list_); \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ if (from_start) \ { \ @@ -397,8 +395,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " \ CMC_(PFX, _sort)(_list_); \ \ - if (_list_->callbacks && _list_->callbacks->read) \ - _list_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_list_, read); \ \ return CMC_(PFX, _impl_binary_search_first)(_list_, value) < _list_->count; \ } \ @@ -456,8 +453,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->resize) \ - _list_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_list_, resize); \ \ return true; \ } \ diff --git a/src/cmc/stack.h b/src/cmc/stack.h index 6207d35..0afa5a3 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -193,6 +193,8 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (capacity < 1) \ return NULL; \ if (!f_val) \ @@ -253,6 +255,8 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " void CMC_(PFX, _customize)(struct SNAME * _stack_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _stack_->alloc = &cmc_alloc_node_default; \ else \ @@ -275,8 +279,7 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " \ _stack_->flag = CMC_FLAG_OK; \ \ - if (_stack_->callbacks && _stack_->callbacks->create) \ - _stack_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_stack_, create); \ \ return true; \ } \ @@ -293,8 +296,7 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " \ _stack_->flag = CMC_FLAG_OK; \ \ - if (_stack_->callbacks && _stack_->callbacks->delete) \ - _stack_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_stack_, delete); \ \ return true; \ } \ @@ -309,8 +311,7 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " \ _stack_->flag = CMC_FLAG_OK; \ \ - if (_stack_->callbacks && _stack_->callbacks->read) \ - _stack_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_stack_, read); \ \ return _stack_->buffer[_stack_->count - 1]; \ } \ @@ -330,8 +331,7 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " } \ } \ \ - if (_stack_->callbacks && _stack_->callbacks->read) \ - _stack_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_stack_, read); \ \ return result; \ } \ @@ -389,8 +389,7 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " \ _stack_->flag = CMC_FLAG_OK; \ \ - if (_stack_->callbacks && _stack_->callbacks->resize) \ - _stack_->callbacks->resize(); \ + CMC_CALLBACKS_CALL(_stack_, resize); \ \ return true; \ } \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index 0591e3b..e653751 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -247,6 +247,8 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!f_key || !f_val) \ return NULL; \ \ @@ -345,6 +347,8 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ else \ @@ -422,8 +426,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " _map_->count++; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->create) \ - _map_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_map_, create); \ \ return true; \ } \ @@ -445,8 +448,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->update) \ - _map_->callbacks->update(); \ + CMC_CALLBACKS_CALL(_map_, update); \ \ return true; \ } \ @@ -584,8 +586,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " _map_->count--; \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->delete) \ - _map_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_map_, delete); \ \ return true; \ } \ @@ -610,8 +611,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return true; \ } \ @@ -636,8 +636,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return true; \ } \ @@ -660,8 +659,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return node->value; \ } \ @@ -684,8 +682,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " \ _map_->flag = CMC_FLAG_OK; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return &(node->value); \ } \ @@ -694,8 +691,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " { \ bool result = CMC_(PFX, _impl_get_node)(_map_, key) != NULL; \ \ - if (_map_->callbacks && _map_->callbacks->read) \ - _map_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_map_, read); \ \ return result; \ } \ diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 6684f0a..300a340 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -232,6 +232,8 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!f_val) \ return NULL; \ \ @@ -325,6 +327,8 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ else \ @@ -402,8 +406,7 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " _set_->count++; \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->create) \ - _set_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_set_, create); \ \ return true; \ } \ @@ -536,8 +539,7 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " _set_->count--; \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->delete) \ - _set_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_set_, delete); \ \ return true; \ } \ @@ -560,8 +562,7 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return true; \ } \ @@ -584,8 +585,7 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " \ _set_->flag = CMC_FLAG_OK; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return true; \ } \ @@ -594,8 +594,7 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " { \ bool result = CMC_(PFX, _impl_get_node)(_set_, value) != NULL; \ \ - if (_set_->callbacks && _set_->callbacks->read) \ - _set_->callbacks->read(); \ + CMC_CALLBACKS_CALL(_set_, read); \ \ return result; \ } \ diff --git a/src/cor/callbacks.h b/src/cor/callbacks.h index 970634f..0ec86a6 100644 --- a/src/cor/callbacks.h +++ b/src/cor/callbacks.h @@ -20,13 +20,15 @@ #ifdef CMC_NO_CALLBACKS #define CMC_CALLBACKS_DECL -#define CMC_CALLBACKS_GET(ds) NULL /* Placeholder for STR */ +#define CMC_CALLBACKS_MAYBE_UNUSED(param) ((void)param) /* Prevent -Wunused-parameter */ +#define CMC_CALLBACKS_GET(ds) NULL /* Helps with compatibility */ #define CMC_CALLBACKS_ASSIGN(ds, cb) #define CMC_CALLBACKS_CALL(ds, cb) #else #define CMC_CALLBACKS_DECL struct CMC_CALLBACKS_NAME *callbacks +#define CMC_CALLBACKS_MAYBE_UNUSED(param) #define CMC_CALLBACKS_GET(ds) (ds)->callbacks #define CMC_CALLBACKS_ASSIGN(ds, cb) CMC_CALLBACKS_GET(ds) = cb #define CMC_CALLBACKS_CALL(ds, cb) \ diff --git a/src/cor/core.h b/src/cor/core.h index 430d35d..5c13c38 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -98,4 +98,14 @@ #define CMC_PARAM_K CMC_TUP_3 #define CMC_PARAM_V CMC_TUP_4 +/** + * Marks a function parameter used or unused depending on the expanded value of + * MACRO. It need to expand to either TRUE or FALSE. + */ +#define CMC_UNUSED_PARAM(MACRO, PARAM) \ + CMC_(CMC_UNUSED_PARAM_, MACRO)(PARAM)\ + +#define CMC_UNUSED_PARAM_FALSE(PARAM) PARAM +#define CMC_UNUSED_PARAM_TRUE(PARAM) + #endif /* CMC_COR_CORE_H */ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 8dc1898..dca4386 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -51,6 +51,8 @@ struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ struct SNAME _deque_ = { 0 }; \ \ if (capacity < 1) \ diff --git a/src/ext/cmc/hashbidimap.h b/src/ext/cmc/hashbidimap.h index 5ae56f5..bf1e423 100644 --- a/src/ext/cmc/hashbidimap.h +++ b/src/ext/cmc/hashbidimap.h @@ -16,6 +16,90 @@ /** * All the EXT parts of CMC HashBidiMap. */ -#define CMC_EXT_CMC_HASHBIDIMAP_PARTS +#define CMC_EXT_CMC_HASHBIDIMAP_PARTS STR + +/** + * STR + */ +#define CMC_EXT_CMC_HASHBIDIMAP_STR(PARAMS) \ + CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(PFX, SNAME, K, V) \ +\ + 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 *key_val_sep); + +#define CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(PFX, SNAME, K, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ + { \ + struct SNAME *m_ = _map_; \ +\ + return 0 <= fprintf(fptr, \ + "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 }", \ + 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, CMC_CALLBACKS_GET(m_)); \ + } \ +\ + 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--) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][0]; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + last = i - 1; \ + break; \ + } \ + } \ +\ + for (size_t i = 0; i < _map_->capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i][0]; \ +\ + if (entry && entry != CMC_ENTRY_DELETED) \ + { \ + 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_HASHBIDIMAP_H */ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index b2adb37..320c8c6 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -57,6 +57,8 @@ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ +\ struct SNAME _map_ = { 0 }; \ \ if (capacity == 0 || load <= 0 || load >= 1) \ diff --git a/src/ext/cmc/list.h b/src/ext/cmc/list.h index e7e3160..63b2294 100644 --- a/src/ext/cmc/list.h +++ b/src/ext/cmc/list.h @@ -296,8 +296,7 @@ _list_->count += size; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -334,8 +333,7 @@ _list_->count += size; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -359,8 +357,7 @@ _list_->count += size; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->create) \ - _list_->callbacks->create(); \ + CMC_CALLBACKS_CALL(_list_, create); \ \ return true; \ } \ @@ -388,8 +385,7 @@ _list_->count -= to - from + 1; \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return true; \ } \ @@ -410,7 +406,7 @@ \ size_t length = to - from + 1; \ \ - struct SNAME *result = CMC_(PFX, _new_custom)(length, _list_->f_val, _list_->alloc, _list_->callbacks); \ + struct SNAME *result = CMC_(PFX, _new_custom)(length, _list_->f_val, _list_->alloc, CMC_CALLBACKS_GET(_list_)); \ \ if (!result) \ { \ @@ -429,8 +425,7 @@ \ _list_->flag = CMC_FLAG_OK; \ \ - if (_list_->callbacks && _list_->callbacks->delete) \ - _list_->callbacks->delete (); \ + CMC_CALLBACKS_CALL(_list_, delete); \ \ return result; \ } diff --git a/src/macro_collections.h b/src/macro_collections.h index d22bcef..59301d3 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -54,6 +54,7 @@ #include "cor/heap.h" /* Added in 01/06/2020 */ #include "ext/cmc/deque.h" /* Added in 25/05/2020 */ +#include "ext/cmc/hashbidimap.h" /* Added in 26/05/2020 */ #include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ #include "ext/cmc/hashmultimap.h" /* Added in 29/05/2020 */ #include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */ diff --git a/tests/to_string.c b/tests/to_string.c index 6d906da..e05c0f3 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -4,6 +4,7 @@ // clang-format off C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm, hashbidimap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int)) @@ -27,6 +28,9 @@ struct int main(void) { struct deque *d = d_new(100, (struct deque_fval *)&int_ftab); + struct hashbidimap *hbm = hbm_new(100, 0.8, + (struct hashbidimap_fkey *)&int_ftab, + (struct hashbidimap_fval *)&int_ftab); struct hashmap *hm = hm_new(100, 0.6, (struct hashmap_fkey *)&int_ftab, (struct hashmap_fval *)&int_ftab); struct hashmultimap *hmm = hmm_new(100, 0.8, @@ -44,6 +48,8 @@ int main(void) d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); + hbm_to_string(hbm, stdout); + hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hm_to_string(hm, stdout); hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hmm_to_string(hmm, stdout); @@ -66,6 +72,7 @@ int main(void) fprintf(stdout, "\n"); d_push_back(d, 0); + hbm_insert(hbm, 0, 0); hm_insert(hm, 0, 0); hmm_insert(hmm, 0, 0); hms_insert(hms, 0); @@ -78,6 +85,8 @@ int main(void) d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); + hbm_to_string(hbm, stdout); + hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hm_to_string(hm, stdout); hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hmm_to_string(hmm, stdout); @@ -100,6 +109,7 @@ int main(void) for (int i = 1; i < 20; i++) { d_push_back(d, i); + hbm_insert(hbm, i, i); hm_insert(hm, i, i); hmm_insert(hmm, i, i); hms_insert(hms, i); @@ -115,6 +125,8 @@ int main(void) d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); + hbm_to_string(hbm, stdout); + hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hm_to_string(hm, stdout); hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); hmm_to_string(hmm, stdout); @@ -135,6 +147,7 @@ int main(void) q_print(q, stdout, "\n[ ", ", ", " ]\n"); d_free(d); + hbm_free(hbm); hm_free(hm); hmm_free(hmm); hms_free(hms); From 649f02665f9d26d79d7a75d52c0617a50bc3d9e3 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sat, 6 Jun 2020 08:32:35 -0300 Subject: [PATCH 25/51] Code formatting and moving more things around --- src/cmc/bitset.h | 4 +- src/cmc/deque.h | 4 +- src/cmc/hashbidimap.h | 6 +- src/cmc/hashmap.h | 4 +- src/cmc/hashmultimap.h | 4 +- src/cmc/hashmultiset.h | 4 +- src/cmc/hashset.h | 4 +- src/cmc/heap.h | 4 +- src/cmc/intervalheap.h | 4 +- src/cmc/linkedlist.h | 4 +- src/cmc/list.h | 4 +- src/cmc/queue.h | 4 +- src/cmc/sortedlist.h | 260 +------------------------------- src/cmc/stack.h | 4 +- src/cmc/treemap.h | 4 +- src/cmc/treeset.h | 4 +- src/cor/core.h | 3 +- src/ext/cmc/deque.h | 2 +- src/ext/cmc/hashmap.h | 2 +- src/ext/cmc/list.h | 3 +- src/ext/cmc/sortedlist.h | 310 +++++++++++++++++++++++++++++++++++++++ src/macro_collections.h | 1 + tests/to_string.c | 11 ++ 23 files changed, 361 insertions(+), 293 deletions(-) create mode 100644 src/ext/cmc/sortedlist.h diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index 25e4915..f4b2a09 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -206,7 +206,7 @@ static const char *cmc_cmc_string_fmt_bitset = "struct %s " struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * CMC_UNUSED(callbacks)) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ struct SNAME _bitset_ = { 0 }; \ \ @@ -245,7 +245,7 @@ static const char *cmc_cmc_string_fmt_bitset = "struct %s " void CMC_(PFX, _customize)(struct SNAME * _bitset_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _bitset_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 74c3956..d2783b4 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -155,7 +155,7 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity < 1) \ return NULL; \ @@ -231,7 +231,7 @@ void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _deque_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index e5ef175..9a92328 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -262,14 +262,14 @@ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ - return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL);\ + return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \ } \ \ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ @@ -350,7 +350,7 @@ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 2eb00a9..c1d7529 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -194,7 +194,7 @@ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ @@ -285,7 +285,7 @@ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index ac79010..b6eb64e 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -223,7 +223,7 @@ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity == 0 || load <= 0) \ return NULL; \ @@ -339,7 +339,7 @@ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index 673613b..0ee8fc2 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -177,7 +177,7 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ @@ -262,7 +262,7 @@ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 7acb6be..1cc9b87 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -156,7 +156,7 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity == 0 || load <= 0 || load >= 1) \ return NULL; \ @@ -240,7 +240,7 @@ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/heap.h b/src/cmc/heap.h index d0d52d2..6d0d19e 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -152,7 +152,7 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity < 1) \ return NULL; \ @@ -223,7 +223,7 @@ void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _heap_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index ad04db3..ac82682 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -146,7 +146,7 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity == 0 || capacity == UINTMAX_MAX) \ return NULL; \ @@ -218,7 +218,7 @@ void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _heap_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index 3e223f6..af1f82c 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -158,7 +158,7 @@ struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!f_val) \ return NULL; \ @@ -216,7 +216,7 @@ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/list.h b/src/cmc/list.h index 0a53453..1e67123 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -165,7 +165,7 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity < 1) \ return NULL; \ @@ -228,7 +228,7 @@ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/queue.h b/src/cmc/queue.h index 652b715..abbc466 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -181,7 +181,7 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity < 1) \ return NULL; \ @@ -256,7 +256,7 @@ void CMC_(PFX, _customize)(struct SNAME * _queue_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _queue_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h index 847f047..34879ed 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc/sortedlist.h @@ -27,21 +27,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * SortedList specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "is_sorted:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core SortedList implementation */ @@ -109,22 +94,6 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " /* Priority function */ \ CMC_DEF_FTAB_PRI(V); \ }; \ -\ - /* List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target list */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ @@ -155,28 +124,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ void CMC_(PFX, _sort)(struct SNAME * _list_); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr); \ -\ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); /* ------------------------------------------------------------------------- * Source @@ -197,7 +145,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity < 1) \ return NULL; \ @@ -258,7 +206,7 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _list_->alloc = &cmc_alloc_node_default; \ @@ -514,208 +462,6 @@ static const char *cmc_cmc_string_fmt_sortedlist = "struct %s<%s> " \ return true; \ } \ -\ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _list_) \ - { \ - struct cmc_string str; \ - struct SNAME *l_ = _list_; \ -\ - int n = \ - snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_sortedlist, #SNAME, #V, l_, l_->buffer, l_->capacity, \ - l_->count, l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, l_->callbacks); \ -\ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr) \ - { \ - CMC_(PFX, _sort)(_list_); \ -\ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - CMC_(PFX, _sort)(target); \ -\ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - CMC_(PFX, _sort)(target); \ -\ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->target->count - 1; \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor += steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } \ \ static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, V value) \ { \ diff --git a/src/cmc/stack.h b/src/cmc/stack.h index 0afa5a3..9a0bf53 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -193,7 +193,7 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (capacity < 1) \ return NULL; \ @@ -255,7 +255,7 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " void CMC_(PFX, _customize)(struct SNAME * _stack_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _stack_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index e653751..e9479b1 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -247,7 +247,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!f_key || !f_val) \ return NULL; \ @@ -347,7 +347,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _map_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 300a340..e4349d5 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -232,7 +232,7 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!f_val) \ return NULL; \ @@ -327,7 +327,7 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!alloc) \ _set_->alloc = &cmc_alloc_node_default; \ diff --git a/src/cor/core.h b/src/cor/core.h index 5c13c38..dc0f400 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -102,8 +102,7 @@ * Marks a function parameter used or unused depending on the expanded value of * MACRO. It need to expand to either TRUE or FALSE. */ -#define CMC_UNUSED_PARAM(MACRO, PARAM) \ - CMC_(CMC_UNUSED_PARAM_, MACRO)(PARAM)\ +#define CMC_UNUSED_PARAM(MACRO, PARAM) CMC_(CMC_UNUSED_PARAM_, MACRO)(PARAM) #define CMC_UNUSED_PARAM_FALSE(PARAM) PARAM #define CMC_UNUSED_PARAM_TRUE(PARAM) diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index dca4386..fb19ec6 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -51,7 +51,7 @@ struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ struct SNAME _deque_ = { 0 }; \ \ diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 320c8c6..89a87de 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -57,7 +57,7 @@ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks);\ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ struct SNAME _map_ = { 0 }; \ \ diff --git a/src/ext/cmc/list.h b/src/ext/cmc/list.h index 63b2294..ad971c8 100644 --- a/src/ext/cmc/list.h +++ b/src/ext/cmc/list.h @@ -406,7 +406,8 @@ \ size_t length = to - from + 1; \ \ - struct SNAME *result = CMC_(PFX, _new_custom)(length, _list_->f_val, _list_->alloc, CMC_CALLBACKS_GET(_list_)); \ + struct SNAME *result = \ + CMC_(PFX, _new_custom)(length, _list_->f_val, _list_->alloc, CMC_CALLBACKS_GET(_list_)); \ \ if (!result) \ { \ diff --git a/src/ext/cmc/sortedlist.h b/src/ext/cmc/sortedlist.h new file mode 100644 index 0000000..fdfe0e4 --- /dev/null +++ b/src/ext/cmc/sortedlist.h @@ -0,0 +1,310 @@ +/** + * ext/cmc/sortedlist.h + * + * Creation Date: 06/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_SORTEDLIST_H +#define CMC_EXT_CMC_SORTEDLIST_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC SortedList. + */ +#define CMC_EXT_CMC_SORTEDLIST_PARTS ITER, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_SORTEDLIST_ITER(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_SORTEDLIST_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* List Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target list */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(PFX, SNAME, V) \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + CMC_(PFX, _sort)(target); \ +\ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + CMC_(PFX, _sort)(target); \ +\ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->target->count - 1; \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor++; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor--; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor += steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor < steps) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->cursor; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_SORTEDLIST_STR(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_SORTEDLIST_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_SORTEDLIST_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ + { \ + struct SNAME *l_ = _list_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "is_sorted:%s, " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->buffer, l_->capacity, l_->count, \ + l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + CMC_(PFX, _sort)(_list_); \ +\ + fprintf(fptr, "%s", start); \ +\ + for (size_t i = 0; i < _list_->count; i++) \ + { \ + if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ + return false; \ +\ + if (i + 1 < _list_->count) \ + fprintf(fptr, "%s", separator); \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ + } + +#endif /* CMC_EXT_CMC_SORTEDLIST_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 59301d3..fcd7c96 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -64,6 +64,7 @@ #include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */ #include "ext/cmc/list.h" /* Added in 04/06/2020 */ #include "ext/cmc/queue.h" /* Added in 05/06/2020 */ +#include "ext/cmc/sortedlist.h" /* Added in 06/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/to_string.c b/tests/to_string.c index e05c0f3..a4de801 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -14,6 +14,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih, intervalheap, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q, queue, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl, sortedlist, , , int)) struct { @@ -45,6 +46,7 @@ int main(void) struct linkedlist *ll = ll_new((struct linkedlist_fval *)&int_ftab); struct list *l = l_new(100, (struct list_fval *)&int_ftab); struct queue *q = q_new(100, (struct queue_fval *)&int_ftab); + struct sortedlist *sl = sl_new(100, (struct sortedlist_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -68,6 +70,8 @@ int main(void) l_print(l, stdout, "\n[ ", ", ", " ]\n"); q_to_string(q, stdout); q_print(q, stdout, "\n[ ", ", ", " ]\n"); + sl_to_string(sl, stdout); + sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -82,6 +86,7 @@ int main(void) ll_push_back(ll, 0); l_push_back(l, 0); q_enqueue(q, 0); + sl_insert(sl, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -105,6 +110,8 @@ int main(void) l_print(l, stdout, "\n[ ", ", ", " ]\n"); q_to_string(q, stdout); q_print(q, stdout, "\n[ ", ", ", " ]\n"); + sl_to_string(sl, stdout); + sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -119,6 +126,7 @@ int main(void) ll_push_back(ll, i); l_push_back(l, i); q_enqueue(q, i); + sl_insert(sl, i); } fprintf(stdout, "\n"); @@ -145,6 +153,8 @@ int main(void) l_print(l, stdout, "\n[ ", ", ", " ]\n"); q_to_string(q, stdout); q_print(q, stdout, "\n[ ", ", ", " ]\n"); + sl_to_string(sl, stdout); + sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hbm_free(hbm); @@ -157,6 +167,7 @@ int main(void) ll_free(ll); l_free(l); q_free(q); + sl_free(sl); } // clang-format on From 1987152b0389a352f880ca9a8c4cea71fc6b2b26 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sun, 7 Jun 2020 16:30:23 -0300 Subject: [PATCH 26/51] More things added to EXT --- src/cmc/stack.h | 260 +-------------------------------- src/ext/cmc/stack.h | 315 ++++++++++++++++++++++++++++++++++++++++ src/macro_collections.h | 1 + tests/to_string.c | 10 ++ 4 files changed, 327 insertions(+), 259 deletions(-) create mode 100644 src/ext/cmc/stack.h diff --git a/src/cmc/stack.h b/src/cmc/stack.h index 9a0bf53..09a1bc4 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -33,20 +33,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * Stack specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core Stack implementation */ @@ -111,22 +97,6 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " /* Priority function */ \ CMC_DEF_FTAB_PRI(V); \ }; \ -\ - /* Stack Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target stack */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ @@ -153,29 +123,7 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " /* Collection Utility */ \ bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity); \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_); \ - bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _stack_); \ - bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr); \ -\ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_); /* ------------------------------------------------------------------------- * Source @@ -436,212 +384,6 @@ static const char *cmc_cmc_string_fmt_stack = "struct %s<%s> " } \ \ return true; \ - } \ -\ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _stack_) \ - { \ - struct cmc_string str; \ - struct SNAME *s_ = _stack_; \ -\ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_stack, #SNAME, #V, s_, s_->buffer, s_->capacity, \ - s_->count, s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ -\ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - { \ - if (!_stack_->f_val->str(fptr, _stack_->buffer[i])) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor--; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor++; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor < steps) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor += steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_advance)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_rewind)(iter, index - iter->cursor); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->target->buffer[iter->cursor]); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return 0; \ -\ - return iter->target->count - 1 - iter->cursor; \ } #endif /* CMC_CMC_STACK_H */ diff --git a/src/ext/cmc/stack.h b/src/ext/cmc/stack.h new file mode 100644 index 0000000..0efdefd --- /dev/null +++ b/src/ext/cmc/stack.h @@ -0,0 +1,315 @@ +/** + * ext/cmc/stack.h + * + * Creation Date: 07/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_STACK_H +#define CMC_EXT_CMC_STACK_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC Stack. + */ +#define CMC_EXT_CMC_STACK_PARTS ITER, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_STACK_ITER(PARAMS) \ + CMC_EXT_CMC_STACK_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_STACK_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_STACK_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_STACK_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_STACK_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_STACK_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_STACK_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* Stack Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target stack */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_STACK_ITER_SOURCE_(PFX, SNAME, V) \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + iter.cursor = target->count - 1; \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = iter->target->count - 1; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->cursor = 0; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor--; \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor++; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == 0) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor < steps) \ + return false; \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor -= steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor + 1 == iter->target->count) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->cursor + steps >= iter->target->count) \ + return false; \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + iter->cursor += steps; \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->cursor > index) \ + return CMC_(PFX, _iter_advance)(iter, iter->cursor - index); \ + else if (iter->cursor < index) \ + return CMC_(PFX, _iter_rewind)(iter, index - iter->cursor); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->target->buffer[iter->cursor]; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->target->buffer[iter->cursor]); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return 0; \ +\ + return iter->target->count - 1 - iter->cursor; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_STACK_STR(PARAMS) \ + CMC_EXT_CMC_STACK_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_STACK_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_STACK_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_STACK_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_STACK_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_STACK_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_STACK_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _stack_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr, const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_STACK_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _stack_, FILE * fptr) \ + { \ + struct SNAME *s_ = _stack_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "buffer:%p, " \ + "capacity:%" PRIuMAX ", " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, s_->flag, \ + s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + for (size_t i = _stack_->count; i > 0; i--) \ + { \ + if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) \ + return false; \ +\ + if (i - 1 != 0) \ + fprintf(fptr, "%s", separator); \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ + } + +#endif /* CMC_EXT_CMC_STACK_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index fcd7c96..845e21a 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -65,6 +65,7 @@ #include "ext/cmc/list.h" /* Added in 04/06/2020 */ #include "ext/cmc/queue.h" /* Added in 05/06/2020 */ #include "ext/cmc/sortedlist.h" /* Added in 06/06/2020 */ +#include "ext/cmc/stack.h" /* Added in 07/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ diff --git a/tests/to_string.c b/tests/to_string.c index a4de801..4f37d45 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -15,6 +15,7 @@ C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q, queue, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl, sortedlist, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s, stack, , , int)) struct { @@ -47,6 +48,7 @@ int main(void) struct list *l = l_new(100, (struct list_fval *)&int_ftab); struct queue *q = q_new(100, (struct queue_fval *)&int_ftab); struct sortedlist *sl = sl_new(100, (struct sortedlist_fval *)&int_ftab); + struct stack *s = s_new(100, (struct stack_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -72,6 +74,8 @@ int main(void) q_print(q, stdout, "\n[ ", ", ", " ]\n"); sl_to_string(sl, stdout); sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); + s_to_string(s, stdout); + s_print(s, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -87,6 +91,7 @@ int main(void) l_push_back(l, 0); q_enqueue(q, 0); sl_insert(sl, 0); + s_push(s, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -112,6 +117,8 @@ int main(void) q_print(q, stdout, "\n[ ", ", ", " ]\n"); sl_to_string(sl, stdout); sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); + s_to_string(s, stdout); + s_print(s, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -127,6 +134,7 @@ int main(void) l_push_back(l, i); q_enqueue(q, i); sl_insert(sl, i); + s_push(s, i); } fprintf(stdout, "\n"); @@ -155,6 +163,8 @@ int main(void) q_print(q, stdout, "\n[ ", ", ", " ]\n"); sl_to_string(sl, stdout); sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); + s_to_string(s, stdout); + s_print(s, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hbm_free(hbm); From aec7efd4c32c1d9d55550bacc938faad61597329 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 8 Jun 2020 20:07:46 -0300 Subject: [PATCH 27/51] Finishing migration to EXT --- src/cmc/bitset.h | 14 +- src/cmc/treemap.h | 378 +--------------------------------- src/cmc/treeset.h | 79 +------ src/ext/cmc/bitset.h | 21 ++ src/ext/cmc/treemap.h | 443 ++++++++++++++++++++++++++++++++++++++++ src/ext/cmc/treeset.h | 126 ++++++++++++ src/macro_collections.h | 3 + 7 files changed, 596 insertions(+), 468 deletions(-) create mode 100644 src/ext/cmc/bitset.h create mode 100644 src/ext/cmc/treemap.h create mode 100644 src/ext/cmc/treeset.h diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index f4b2a09..6872533 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -41,18 +41,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/bitset.h" -/* ------------------------------------------------------------------------- - * BitSet specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_bitset = "struct %s " - "at %p { " - "buffer:%p, " - "capacity:%" PRIuMAX ", " - "flag:%d, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core BitSet implementation */ @@ -95,7 +83,7 @@ static const char *cmc_cmc_string_fmt_bitset = "struct %s " struct SNAME *target; \ \ /* Cursor's position (index) */ \ - cmc_bitset_word cursor; \ + size_t cursor; \ \ /* If the iterator has reached the start of the iteration */ \ bool start; \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index e9479b1..3464bd5 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -24,20 +24,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * TreeMap specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " - "at %p { " - "root:%p, " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "f_key:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core TreeMap implementation */ @@ -148,31 +134,6 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " /* Priority function */ \ CMC_DEF_FTAB_PRI(V); \ }; \ -\ - /* Treemap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target treemap */ \ - struct SNAME *target; \ -\ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ -\ - /* The first node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * first; \ -\ - /* The last node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * last; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ @@ -200,30 +161,7 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " int CMC_(PFX, _flag)(struct SNAME * _map_); \ /* Collection Utility */ \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr); \ -\ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); /* ------------------------------------------------------------------------- * Source @@ -769,320 +707,6 @@ static const char *cmc_cmc_string_fmt_treemap = "struct %s<%s, %s> " \ return true; \ } \ -\ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _map_) \ - { \ - struct cmc_string str; \ - struct SNAME *m_ = _map_; \ -\ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treemap, #SNAME, #K, #V, m_, m_->root, m_->count, \ - m_->flag, m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \ -\ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = _map_->root; \ -\ - bool left_done = false; \ -\ - while (root) \ - { \ - if (!left_done) \ - { \ - while (root->left) \ - root = root->left; \ - } \ -\ - if (!_map_->f_key->str(fptr, root->key) && !_map_->f_val->str(fptr, root->value)) \ - return false; \ -\ - left_done = true; \ -\ - if (root->right) \ - { \ - left_done = false; \ - root = root->right; \ - } \ - else if (root->parent) \ - { \ - while (root->parent && root == root->parent->right) \ - root = root->parent; \ -\ - if (!root->parent) \ - break; \ -\ - root = root->parent; \ - } \ - else \ - break; \ - } \ -\ - return true; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->left != NULL) \ - iter.cursor = iter.cursor->left; \ -\ - iter.first = iter.cursor; \ -\ - iter.last = target->root; \ - while (iter.last->right != NULL) \ - iter.last = iter.last->right; \ - } \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->right != NULL) \ - iter.cursor = iter.cursor->right; \ -\ - iter.last = iter.cursor; \ -\ - iter.first = target->root; \ - while (iter.first->left != NULL) \ - iter.first = iter.first->left; \ -\ - iter.index = target->count - 1; \ - } \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->first; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->cursor = iter->last; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->right != NULL) \ - { \ - iter->cursor = iter->cursor->right; \ -\ - while (iter->cursor->left != NULL) \ - iter->cursor = iter->cursor->left; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->left == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->left != NULL) \ - { \ - iter->cursor = iter->cursor->left; \ -\ - while (iter->cursor->right != NULL) \ - iter->cursor = iter->cursor->right; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->right == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ -\ - return iter->cursor->key; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->cursor->value; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->cursor->value); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ \ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value) \ { \ diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index e4349d5..7219092 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -24,19 +24,6 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * TreeSet specific - * ------------------------------------------------------------------------- */ -/* to_string format */ -static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " - "at %p { " - "root:%p, " - "count:%" PRIuMAX ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }"; - /** * Core TreeSet implementation */ @@ -167,8 +154,6 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " /* Collection Utility */ \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr); \ \ /* Set Operations */ \ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ @@ -198,17 +183,7 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ /* Iterator Access */ \ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ -\ - /* Default Value */ \ - static inline V CMC_(PFX, _impl_default_value)(void) \ - { \ - V _empty_value_; \ -\ - memset(&_empty_value_, 0, sizeof(V)); \ -\ - return _empty_value_; \ - } + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); /* ------------------------------------------------------------------------- * Source @@ -662,58 +637,6 @@ static const char *cmc_cmc_string_fmt_treeset = "struct %s<%s> " \ return true; \ } \ -\ - struct cmc_string CMC_(PFX, _to_string)(struct SNAME * _set_) \ - { \ - struct cmc_string str; \ - struct SNAME *s_ = _set_; \ -\ - int n = snprintf(str.s, cmc_string_len, cmc_cmc_string_fmt_treeset, #SNAME, #V, s_, s_->root, s_->count, \ - s_->flag, s_->f_val, s_->alloc, s_->callbacks); \ -\ - return n >= 0 ? str : (struct cmc_string){ 0 }; \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = _set_->root; \ -\ - bool left_done = false; \ -\ - while (root) \ - { \ - if (!left_done) \ - { \ - while (root->left) \ - root = root->left; \ - } \ -\ - if (!_set_->f_val->str(fptr, root->value)) \ - return false; \ -\ - left_done = true; \ -\ - if (root->right) \ - { \ - left_done = false; \ - root = root->right; \ - } \ - else if (root->parent) \ - { \ - while (root->parent && root == root->parent->right) \ - root = root->parent; \ -\ - if (!root->parent) \ - break; \ -\ - root = root->parent; \ - } \ - else \ - break; \ - } \ -\ - return true; \ - } \ \ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ { \ diff --git a/src/ext/cmc/bitset.h b/src/ext/cmc/bitset.h new file mode 100644 index 0000000..994c07e --- /dev/null +++ b/src/ext/cmc/bitset.h @@ -0,0 +1,21 @@ +/** + * ext/cmc/bitset.h + * + * Creation Date: 08/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_BITSET_H +#define CMC_EXT_CMC_BITSET_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC BitSet. + */ +#define CMC_EXT_CMC_BITSET_PARTS + +#endif /* CMC_EXT_CMC_BITSET_H */ diff --git a/src/ext/cmc/treemap.h b/src/ext/cmc/treemap.h new file mode 100644 index 0000000..cf45ad0 --- /dev/null +++ b/src/ext/cmc/treemap.h @@ -0,0 +1,443 @@ +/** + * ext/cmc/treemap.h + * + * Creation Date: 08/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_TREEMAP_H +#define CMC_EXT_CMC_TREEMAP_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC TreeMap. + */ +#define CMC_EXT_CMC_TREEMAP_PARTS ITER, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_TREEMAP_ITER(PARAMS) \ + CMC_EXT_CMC_TREEMAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_TREEMAP_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_TREEMAP_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_TREEMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREEMAP_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREEMAP_ITER_HEADER_(PFX, SNAME, K, V) \ +\ + /* Treemap Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target treemap */ \ + struct SNAME *target; \ +\ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ +\ + /* The first node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * first; \ +\ + /* The last node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * last; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->left != NULL) \ + iter.cursor = iter.cursor->left; \ +\ + iter.first = iter.cursor; \ +\ + iter.last = target->root; \ + while (iter.last->right != NULL) \ + iter.last = iter.last->right; \ + } \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->right != NULL) \ + iter.cursor = iter.cursor->right; \ +\ + iter.last = iter.cursor; \ +\ + iter.first = target->root; \ + while (iter.first->left != NULL) \ + iter.first = iter.first->left; \ +\ + iter.index = target->count - 1; \ + } \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->first; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + iter->cursor = iter->last; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->right != NULL) \ + { \ + iter->cursor = iter->cursor->right; \ +\ + while (iter->cursor->left != NULL) \ + iter->cursor = iter->cursor->left; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->left == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->left != NULL) \ + { \ + iter->cursor = iter->cursor->left; \ +\ + while (iter->cursor->right != NULL) \ + iter->cursor = iter->cursor->right; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->right == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (K){ 0 }; \ +\ + return iter->cursor->key; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->cursor->value; \ + } \ +\ + V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return NULL; \ +\ + return &(iter->cursor->value); \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * STR + */ +#define CMC_EXT_CMC_TREEMAP_STR(PARAMS) \ + CMC_EXT_CMC_TREEMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_TREEMAP_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_TREEMAP_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_TREEMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREEMAP_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREEMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREEMAP_STR_HEADER_(PFX, SNAME, K, V) \ +\ + 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 *key_val_sep); + +#define CMC_EXT_CMC_TREEMAP_STR_SOURCE_(PFX, SNAME, K, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ + { \ + struct SNAME *m_ = _map_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s, %s> " \ + "at %p { " \ + "root:%p, " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "f_key:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->root, m_->count, \ + m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \ + } \ +\ + 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); \ +\ + struct CMC_DEF_NODE(SNAME) *root = _map_->root; \ +\ + bool left_done = false; \ +\ + size_t i = 0; \ + while (root) \ + { \ + if (!left_done) \ + { \ + while (root->left) \ + root = root->left; \ + } \ +\ + if (!_map_->f_key->str(fptr, root->key)) \ + return false; \ +\ + fprintf(fptr, "%s", key_val_sep); \ +\ + if (!_map_->f_val->str(fptr, root->value)) \ + return false; \ +\ + if (++i < _map_->count) \ + fprintf(fptr, "%s", separator); \ +\ + left_done = true; \ +\ + if (root->right) \ + { \ + left_done = false; \ + root = root->right; \ + } \ + else if (root->parent) \ + { \ + while (root->parent && root == root->parent->right) \ + root = root->parent; \ +\ + if (!root->parent) \ + break; \ +\ + root = root->parent; \ + } \ + else \ + break; \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ + } + +#endif /* CMC_EXT_CMC_TREEMAP_H */ diff --git a/src/ext/cmc/treeset.h b/src/ext/cmc/treeset.h new file mode 100644 index 0000000..1e4f32d --- /dev/null +++ b/src/ext/cmc/treeset.h @@ -0,0 +1,126 @@ +/** + * ext/cmc/treeset.h + * + * Creation Date: 08/06/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_CMC_TREESET_H +#define CMC_EXT_CMC_TREESET_H + +#include "../../cor/core.h" + +/** + * All the EXT parts of CMC TreeSet. + */ +#define CMC_EXT_CMC_TREESET_PARTS ITER, STR + +/** + * ITER + */ +#define CMC_EXT_CMC_TREESET_ITER(PARAMS) \ + CMC_EXT_CMC_TREESET_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_ITER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_TREESET_ITER_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_ITER_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREESET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_ITER_HEADER_(PFX, SNAME, V) + +#define CMC_EXT_CMC_TREESET_ITER_SOURCE_(PFX, SNAME, V) + +/** + * STR + */ +#define CMC_EXT_CMC_TREESET_STR(PARAMS) \ + CMC_EXT_CMC_TREESET_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_STR_SOURCE(PARAMS) + +#define CMC_EXT_CMC_TREESET_STR_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_STR_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREESET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_STR_HEADER_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ + const char *end); + +#define CMC_EXT_CMC_TREESET_STR_SOURCE_(PFX, SNAME, V) \ +\ + bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ + { \ + struct SNAME *s_ = _set_; \ +\ + return 0 <= fprintf(fptr, \ + "struct %s<%s> " \ + "at %p { " \ + "root:%p, " \ + "count:%" PRIuMAX ", " \ + "flag:%d, " \ + "f_val:%p, " \ + "alloc:%p, " \ + "callbacks:%p }", \ + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->root, s_->count, s_->flag, s_->f_val, \ + s_->alloc, CMC_CALLBACKS_GET(s_)); \ + } \ +\ + bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ + const char *end) \ + { \ + fprintf(fptr, "%s", start); \ +\ + struct CMC_DEF_NODE(SNAME) *root = _set_->root; \ +\ + bool left_done = false; \ +\ + size_t i = 0; \ + while (root) \ + { \ + if (!left_done) \ + { \ + while (root->left) \ + root = root->left; \ + } \ +\ + if (!_set_->f_val->str(fptr, root->value)) \ + return false; \ +\ + if (++i < _set_->count) \ + fprintf(fptr, "%s", separator); \ +\ + left_done = true; \ +\ + if (root->right) \ + { \ + left_done = false; \ + root = root->right; \ + } \ + else if (root->parent) \ + { \ + while (root->parent && root == root->parent->right) \ + root = root->parent; \ +\ + if (!root->parent) \ + break; \ +\ + root = root->parent; \ + } \ + else \ + break; \ + } \ +\ + fprintf(fptr, "%s", end); \ +\ + return true; \ + } + +#endif /* CMC_EXT_CMC_TREESET_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 845e21a..a19ff94 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -53,6 +53,7 @@ #include "cor/hashtable.h" /* Added in 17/03/2020 */ #include "cor/heap.h" /* Added in 01/06/2020 */ +#include "ext/cmc/bitset.h" /* Added in 08/06/2020 */ #include "ext/cmc/deque.h" /* Added in 25/05/2020 */ #include "ext/cmc/hashbidimap.h" /* Added in 26/05/2020 */ #include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ @@ -66,6 +67,8 @@ #include "ext/cmc/queue.h" /* Added in 05/06/2020 */ #include "ext/cmc/sortedlist.h" /* Added in 06/06/2020 */ #include "ext/cmc/stack.h" /* Added in 07/06/2020 */ +#include "ext/cmc/treemap.h" /* Added in 08/06/2020 */ +#include "ext/cmc/treeset.h" /* Added in 08/06/2020 */ #include "utl/assert.h" /* Added in 27/06/2019 */ #include "utl/foreach.h" /* Added in 25/02/2019 */ From 2b8f778c59e0fec4b61a33daaa7edb0228f62ae3 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 8 Jun 2020 21:14:56 -0300 Subject: [PATCH 28/51] Fixing some things, tests resumed --- autogen.py | 4 +- src/cmc/hashmap.h | 10 +- src/ext/cmc/bitset.h | 11 +- src/utl/test.h | 15 - tests/main/Makefile | 2 +- tests/main/src/bitset.c | 63 ++-- tests/main/src/deque.c | 166 ++++++--- tests/main/src/hashbidimap.c | 155 +++++--- tests/main/src/hashmap.c | 334 +++++++++++------ tests/main/src/hashmultimap.c | 263 ++++++++------ tests/main/src/hashmultiset.c | 667 ++++++++++++++++++---------------- tests/main/src/hashset.c | 480 ++++++++++++------------ tests/main/src/heap.c | 190 +++++----- tests/main/src/intervalheap.c | 389 ++++++++++---------- tests/main/src/linkedlist.c | 434 ++++++++++++---------- tests/main/src/list.c | 398 +++++++++++--------- tests/main/src/queue.c | 102 ++++-- tests/main/src/sortedlist.c | 291 ++++++++------- tests/main/src/stack.c | 107 +++--- tests/main/src/treemap.c | 355 ++++++++++-------- tests/main/src/treeset.c | 123 +++++-- tests/main/unt/bitset.c | 5 +- tests/main/unt/hashbidimap.c | 11 +- tests/main/unt/heap.c | 1 - tests/main/unt/utl.c | 5 + tests/to_string.c | 24 ++ 26 files changed, 2652 insertions(+), 1953 deletions(-) diff --git a/autogen.py b/autogen.py index fe8b08d..476ee47 100644 --- a/autogen.py +++ b/autogen.py @@ -53,11 +53,11 @@ for data in collections: file.write( f''' - #include {data['h']} + #include "macro_collections.h" {UNIQUE_FLAG} - CMC_{data['LIB']}_{data['COLLECTION']}_CORE(({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) + C_MACRO_COLLECTIONS_ALL({data['LIB']}, {data['COLLECTION']}, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) {UNIQUE_FLAG} ''') diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index c1d7529..c0e2e06 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -453,8 +453,8 @@ { \ if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ { \ - max_key = _map_->buffer[first].key; \ - max_val = _map_->buffer[first].value; \ + max_key = _map_->buffer[i].key; \ + max_val = _map_->buffer[i].value; \ } \ } \ } \ @@ -495,10 +495,10 @@ { \ if (_map_->buffer[i].state == CMC_ES_FILLED) \ { \ - if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) > 0) \ + if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \ { \ - min_key = _map_->buffer[first].key; \ - min_val = _map_->buffer[first].value; \ + min_key = _map_->buffer[i].key; \ + min_val = _map_->buffer[i].value; \ } \ } \ } \ diff --git a/src/ext/cmc/bitset.h b/src/ext/cmc/bitset.h index 994c07e..791abcc 100644 --- a/src/ext/cmc/bitset.h +++ b/src/ext/cmc/bitset.h @@ -16,6 +16,15 @@ /** * All the EXT parts of CMC BitSet. */ -#define CMC_EXT_CMC_BITSET_PARTS +#define CMC_EXT_CMC_BITSET_PARTS PLACEHOLDER + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER(PARAMS) + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER(PARAMS) + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE(PARAMS) + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER_(PFX, SNAME, V) +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE_(PFX, SNAME, V) #endif /* CMC_EXT_CMC_BITSET_H */ diff --git a/src/utl/test.h b/src/utl/test.h index f604489..07238c2 100644 --- a/src/utl/test.h +++ b/src/utl/test.h @@ -136,12 +136,6 @@ CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_t BODY; \ \ cmc_timer_stop(timer); \ -\ - unittest_abort: \ - if (tinfo.aborted) \ - { \ - cmc_test_log(unit_name, current_test, true, false); \ - } \ \ tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \ tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \ @@ -225,13 +219,4 @@ CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_t \ } while (0) -#define CMC_TEST_ABORT() \ - do \ - { \ - tinfo.aborted = true; \ - tinfo.total -= 1; \ - goto unittest_abort; \ -\ - } while (0) - #endif /* CMC_UTL_TEST_H */ diff --git a/tests/main/Makefile b/tests/main/Makefile index 2cf7991..f207ef3 100644 --- a/tests/main/Makefile +++ b/tests/main/Makefile @@ -1,6 +1,6 @@ CC = gcc CFLAGS = -std=c11 -Wall -Wextra -CFLAGS += -Wno-unused -Wno-missing-braces +CFLAGS += -Wno-missing-braces DBFLAGS = -g3 CVFLAGS = --coverage -O0 INCLUDE = ../../src/ diff --git a/tests/main/src/bitset.c b/tests/main/src/bitset.c index 93f3f3c..6fc38ba 100644 --- a/tests/main/src/bitset.c +++ b/tests/main/src/bitset.c @@ -14,7 +14,7 @@ struct bitset struct bitset_iter { struct bitset *target; - cmc_bitset_word cursor; + size_t cursor; _Bool start; _Bool end; }; @@ -70,15 +70,17 @@ struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct _bitset_->capacity = capacity; _bitset_->flag = CMC_FLAG_OK; _bitset_->alloc = alloc; - _bitset_->callbacks = callbacks; + (_bitset_)->callbacks = callbacks; return _bitset_; } struct bitset bs_init(size_t n_bits) { return bs_init_custom(n_bits, ((void *)0), ((void *)0)); } -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, + struct cmc_callbacks *__attribute__((__unused__)) (callbacks)) { + ; struct bitset _bitset_ = { 0 }; if (n_bits < 1) return _bitset_; @@ -91,7 +93,7 @@ struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct _bitset_.capacity = capacity; _bitset_.flag = CMC_FLAG_OK; _bitset_.alloc = alloc; - _bitset_.callbacks = callbacks; + (&_bitset_)->callbacks = callbacks; return _bitset_; } void bs_free(struct bitset *_bitset_) @@ -105,11 +107,12 @@ void bs_release(struct bitset _bitset_) } void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _bitset_->alloc = &cmc_alloc_node_default; else _bitset_->alloc = alloc; - _bitset_->callbacks = callbacks; + (_bitset_)->callbacks = callbacks; _bitset_->flag = CMC_FLAG_OK; } _Bool bs_set(struct bitset *_bitset_, size_t bit_index) @@ -120,8 +123,9 @@ _Bool bs_set(struct bitset *_bitset_, size_t bit_index) size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->create) - _bitset_->callbacks->create(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; return 1; } _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) @@ -153,8 +157,9 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[end_index] |= end_mask; } _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->create) - _bitset_->callbacks->create(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; return 1; } _Bool bs_clear(struct bitset *_bitset_, size_t bit_index) @@ -165,8 +170,9 @@ _Bool bs_clear(struct bitset *_bitset_, size_t bit_index) size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->delete) - _bitset_->callbacks->delete (); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) + (_bitset_)->callbacks->delete (); + ; return 1; } _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) @@ -198,8 +204,9 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[end_index] &= ~end_mask; } _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->delete) - _bitset_->callbacks->delete (); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) + (_bitset_)->callbacks->delete (); + ; return 1; } _Bool bs_flip(struct bitset *_bitset_, size_t bit_index) @@ -210,8 +217,9 @@ _Bool bs_flip(struct bitset *_bitset_, size_t bit_index) size_t i = bs_bit_to_index(bit_index); _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->update) - _bitset_->callbacks->update(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) + (_bitset_)->callbacks->update(); + ; return 1; } _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) @@ -243,8 +251,9 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[end_index] ^= end_mask; } _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->update) - _bitset_->callbacks->update(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) + (_bitset_)->callbacks->update(); + ; return 1; } _Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state) @@ -266,8 +275,9 @@ _Bool bs_set_all(struct bitset *_bitset_) for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = ~((cmc_bitset_word)0); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->create) - _bitset_->callbacks->create(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; return 1; } _Bool bs_clear_all(struct bitset *_bitset_) @@ -275,8 +285,9 @@ _Bool bs_clear_all(struct bitset *_bitset_) for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = 0; _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->delete) - _bitset_->callbacks->delete (); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) + (_bitset_)->callbacks->delete (); + ; return 1; } _Bool bs_flip_all(struct bitset *_bitset_) @@ -284,8 +295,9 @@ _Bool bs_flip_all(struct bitset *_bitset_) for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); _bitset_->flag = CMC_FLAG_OK; - if (_bitset_->callbacks && _bitset_->callbacks->create) - _bitset_->callbacks->create(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; return 1; } _Bool bs_get(struct bitset *_bitset_, size_t bit_index) @@ -318,8 +330,9 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) if (_bitset_->capacity < words) memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word)); _bitset_->capacity = words; - if (_bitset_->callbacks && _bitset_->callbacks->resize) - _bitset_->callbacks->resize(); + if ((_bitset_)->callbacks && (_bitset_)->callbacks->resize) + (_bitset_)->callbacks->resize(); + ; _bitset_->flag = CMC_FLAG_OK; return 1; } diff --git a/tests/main/src/deque.c b/tests/main/src/deque.c index 8d83464..dc5f600 100644 --- a/tests/main/src/deque.c +++ b/tests/main/src/deque.c @@ -24,20 +24,11 @@ struct deque_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct deque_iter -{ - struct deque *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; struct deque *d_new(size_t capacity, struct deque_fval *f_val); struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void d_clear(struct deque *_deque_); void d_free(struct deque *_deque_); -void d_release(struct deque _deque_); void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool d_push_front(struct deque *_deque_, size_t value); _Bool d_push_back(struct deque *_deque_, size_t value); @@ -54,8 +45,18 @@ int d_flag(struct deque *_deque_); _Bool d_resize(struct deque *_deque_, size_t capacity); struct deque *d_copy_of(struct deque *_deque_); _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_); -struct cmc_string d_to_string(struct deque *_deque_); -_Bool d_print(struct deque *_deque_, FILE *fptr); +struct deque d_init(size_t capacity, struct deque_fval *f_val); +struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void d_release(struct deque _deque_); +struct deque_iter +{ + struct deque *target; + size_t cursor; + size_t index; + _Bool start; + _Bool end; +}; struct deque_iter d_iter_start(struct deque *target); struct deque_iter d_iter_end(struct deque *target); _Bool d_iter_at_start(struct deque_iter *iter); @@ -70,6 +71,8 @@ _Bool d_iter_go_to(struct deque_iter *iter, size_t index); size_t d_iter_value(struct deque_iter *iter); size_t *d_iter_rvalue(struct deque_iter *iter); size_t d_iter_index(struct deque_iter *iter); +_Bool d_to_string(struct deque *_deque_, FILE *fptr); +_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end); struct deque *d_new(size_t capacity, struct deque_fval *f_val) { return d_new_custom(capacity, f_val, ((void *)0), ((void *)0)); @@ -77,6 +80,7 @@ struct deque *d_new(size_t capacity, struct deque_fval *f_val) struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!f_val) @@ -99,7 +103,7 @@ struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc _deque_->flag = CMC_FLAG_OK; _deque_->f_val = f_val; _deque_->alloc = alloc; - _deque_->callbacks = callbacks; + (_deque_)->callbacks = callbacks; return _deque_; } void d_clear(struct deque *_deque_) @@ -131,25 +135,14 @@ void d_free(struct deque *_deque_) _deque_->alloc->free(_deque_->buffer); _deque_->alloc->free(_deque_); } -void d_release(struct deque _deque_) -{ - if (_deque_.f_val->free) - { - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) - { - _deque_.f_val->free(_deque_.buffer[i]); - i = (i + 1) % _deque_.capacity; - } - } - _deque_.alloc->free(_deque_.buffer); -} void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _deque_->alloc = &cmc_alloc_node_default; else _deque_->alloc = alloc; - _deque_->callbacks = callbacks; + (_deque_)->callbacks = callbacks; _deque_->flag = CMC_FLAG_OK; } _Bool d_push_front(struct deque *_deque_, size_t value) @@ -163,8 +156,9 @@ _Bool d_push_front(struct deque *_deque_, size_t value) _deque_->buffer[_deque_->front] = value; _deque_->count++; _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->create) - _deque_->callbacks->create(); + if ((_deque_)->callbacks && (_deque_)->callbacks->create) + (_deque_)->callbacks->create(); + ; return 1; } _Bool d_push_back(struct deque *_deque_, size_t value) @@ -178,8 +172,9 @@ _Bool d_push_back(struct deque *_deque_, size_t value) _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; _deque_->count++; _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->create) - _deque_->callbacks->create(); + if ((_deque_)->callbacks && (_deque_)->callbacks->create) + (_deque_)->callbacks->create(); + ; return 1; } _Bool d_pop_front(struct deque *_deque_) @@ -193,8 +188,9 @@ _Bool d_pop_front(struct deque *_deque_) _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; _deque_->count--; _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->delete) - _deque_->callbacks->delete (); + if ((_deque_)->callbacks && (_deque_)->callbacks->delete) + (_deque_)->callbacks->delete (); + ; return 1; } _Bool d_pop_back(struct deque *_deque_) @@ -208,8 +204,9 @@ _Bool d_pop_back(struct deque *_deque_) _deque_->buffer[_deque_->back] = (size_t){ 0 }; _deque_->count--; _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->delete) - _deque_->callbacks->delete (); + if ((_deque_)->callbacks && (_deque_)->callbacks->delete) + (_deque_)->callbacks->delete (); + ; return 1; } size_t d_front(struct deque *_deque_) @@ -220,8 +217,9 @@ size_t d_front(struct deque *_deque_) return (size_t){ 0 }; } _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->read) - _deque_->callbacks->read(); + if ((_deque_)->callbacks && (_deque_)->callbacks->read) + (_deque_)->callbacks->read(); + ; return _deque_->buffer[_deque_->front]; } size_t d_back(struct deque *_deque_) @@ -232,8 +230,9 @@ size_t d_back(struct deque *_deque_) return (size_t){ 0 }; } _deque_->flag = CMC_FLAG_OK; - if (_deque_->callbacks && _deque_->callbacks->read) - _deque_->callbacks->read(); + if ((_deque_)->callbacks && (_deque_)->callbacks->read) + (_deque_)->callbacks->read(); + ; return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; } _Bool d_contains(struct deque *_deque_, size_t value) @@ -249,8 +248,9 @@ _Bool d_contains(struct deque *_deque_, size_t value) } i = (i + 1) % _deque_->capacity; } - if (_deque_->callbacks && _deque_->callbacks->read) - _deque_->callbacks->read(); + if ((_deque_)->callbacks && (_deque_)->callbacks->read) + (_deque_)->callbacks->read(); + ; return result; } _Bool d_empty(struct deque *_deque_) @@ -300,18 +300,20 @@ _Bool d_resize(struct deque *_deque_, size_t capacity) _deque_->front = 0; _deque_->back = _deque_->count; success: - if (_deque_->callbacks && _deque_->callbacks->resize) - _deque_->callbacks->resize(); + if ((_deque_)->callbacks && (_deque_)->callbacks->resize) + (_deque_)->callbacks->resize(); + ; return 1; } struct deque *d_copy_of(struct deque *_deque_) { - struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, _deque_->callbacks); + struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0)); if (!result) { _deque_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _deque_->callbacks; if (_deque_->f_val->cpy) { for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) @@ -350,6 +352,46 @@ _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_) } return 1; } +struct deque d_init(size_t capacity, struct deque_fval *f_val) +{ + return d_init_custom(capacity, f_val, ((void *)0), ((void *)0)); +} +struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + struct deque _deque_ = { 0 }; + if (capacity < 1) + return _deque_; + if (!f_val) + return _deque_; + if (!alloc) + alloc = &cmc_alloc_node_default; + _deque_.buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_deque_.buffer) + return _deque_; + _deque_.capacity = capacity; + _deque_.count = 0; + _deque_.front = 0; + _deque_.back = 0; + _deque_.flag = CMC_FLAG_OK; + _deque_.f_val = f_val; + _deque_.alloc = alloc; + (&_deque_)->callbacks = callbacks; + return _deque_; +} +void d_release(struct deque _deque_) +{ + if (_deque_.f_val->free) + { + for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) + { + _deque_.f_val->free(_deque_.buffer[i]); + i = (i + 1) % _deque_.capacity; + } + } + _deque_.alloc->free(_deque_.buffer); +} struct deque_iter d_iter_start(struct deque *target) { struct deque_iter iter; @@ -504,5 +546,45 @@ size_t d_iter_index(struct deque_iter *iter) { return iter->index; } +_Bool d_to_string(struct deque *_deque_, FILE *fptr) +{ + struct deque *d_ = _deque_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "front:%" + "I64u" + ", " + "back:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag, + d_->f_val, d_->alloc, (d_)->callbacks); +} +_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) + return 0; + i = (i + 1) % _deque_->capacity; + if (j + 1 < _deque_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_DEQUE */ diff --git a/tests/main/src/hashbidimap.c b/tests/main/src/hashbidimap.c index 32029fd..42e2c8d 100644 --- a/tests/main/src/hashbidimap.c +++ b/tests/main/src/hashbidimap.c @@ -78,8 +78,6 @@ int hbm_flag(struct hashbidimap *_map_); _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity); struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_); _Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_); -struct cmc_string hbm_to_string(struct hashbidimap *_map_); -_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr); struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target); void hbm_iter_free(struct hashbidimap_iter *iter); void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target); @@ -95,6 +93,9 @@ _Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); size_t hbm_iter_key(struct hashbidimap_iter *iter); size_t hbm_iter_value(struct hashbidimap_iter *iter); size_t hbm_iter_index(struct hashbidimap_iter *iter); +_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr); +_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value); static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key); static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val); @@ -106,40 +107,13 @@ static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_); struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, struct hashbidimap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hbm_impl_calculate_size(capacity / load); - struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); - if (!_map_->buffer) - { - alloc->free(_map_->buffer); - alloc->free(_map_); - return ((void *)0); - } - _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 = ((void *)0); - _map_->it_start = hbm_impl_it_start; - _map_->it_end = hbm_impl_it_end; - return _map_; + return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -167,7 +141,7 @@ struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidi _map_->f_val = f_val; _map_->flag = CMC_FLAG_OK; _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->it_start = hbm_impl_it_start; _map_->it_end = hbm_impl_it_end; return _map_; @@ -199,11 +173,12 @@ void hbm_free(struct hashbidimap *_map_) } void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) @@ -233,8 +208,9 @@ _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) } _map_->count++; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->create) - _map_->callbacks->create(); + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; return 1; } _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) @@ -277,8 +253,9 @@ _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) } success: _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) @@ -321,8 +298,9 @@ _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) } success: _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val) @@ -354,8 +332,9 @@ _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, *val_entry = ((void *)1); _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } _Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val) @@ -387,8 +366,9 @@ _Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, *val_entry = ((void *)1); _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } size_t hbm_get_key(struct hashbidimap *_map_, size_t val) @@ -400,8 +380,9 @@ size_t hbm_get_key(struct hashbidimap *_map_, size_t val) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return (*entry)->key; } size_t hbm_get_val(struct hashbidimap *_map_, size_t key) @@ -413,24 +394,27 @@ size_t hbm_get_val(struct hashbidimap *_map_, size_t key) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return (*entry)->value; } _Bool hbm_contains_key(struct hashbidimap *_map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool hbm_contains_val(struct hashbidimap *_map_, size_t val) { _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool hbm_empty(struct hashbidimap *_map_) @@ -516,19 +500,21 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) _map_->alloc->free(tmp_buff); _map_->alloc->free(_new_map_); success: - if (_map_->callbacks && _map_->callbacks->resize) - _map_->callbacks->resize(); + if ((_map_)->callbacks && (_map_)->callbacks->resize) + (_map_)->callbacks->resize(); + ; return 1; } struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) { struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, _map_->callbacks); + _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _map_->callbacks; for (size_t i = 0; i < _map_->capacity; i++) { struct hashbidimap_entry *scan = _map_->buffer[i][0]; @@ -607,8 +593,8 @@ void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target) { for (size_t i = 0; i < target->capacity; i++) { - struct hashbidimap_entry *tmp = target->buffer[i][0]; - if (tmp != ((void *)0) && tmp != ((void *)1)) + struct hashbidimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) { iter->first = i; break; @@ -617,8 +603,8 @@ void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target) iter->cursor = iter->first; for (size_t i = target->capacity; i > 0; i--) { - struct hashbidimap_entry *tmp = target->buffer[i - 1][0]; - if (tmp != ((void *)0) && tmp != ((void *)1)) + struct hashbidimap_entry *entry = target->buffer[i - 1][0]; + if (entry && entry != ((void *)1)) { iter->last = i - 1; break; @@ -910,5 +896,58 @@ static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_) hbm_iter_to_end(&iter); return iter; } +_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr) +{ + struct hashbidimap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); +} +_Bool hbm_print(struct hashbidimap *_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--) + { + struct hashbidimap_entry *entry = _map_->buffer[i - 1][0]; + if (entry && entry != ((void *)1)) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashbidimap_entry *entry = _map_->buffer[i][0]; + if (entry && entry != ((void *)1)) + { + if (!_map_->f_key->str(fptr, entry->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_HASHBIDIMAP */ diff --git a/tests/main/src/hashmap.c b/tests/main/src/hashmap.c index d9b1f95..37980ab 100644 --- a/tests/main/src/hashmap.c +++ b/tests/main/src/hashmap.c @@ -40,22 +40,11 @@ struct hashmap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct hashmap_iter -{ - struct hashmap *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); void hm_clear(struct hashmap *_map_); void hm_free(struct hashmap *_map_); -void hm_release(struct hashmap _map_); void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); _Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value); @@ -74,8 +63,20 @@ int hm_flag(struct hashmap *_map_); _Bool hm_resize(struct hashmap *_map_, size_t capacity); struct hashmap *hm_copy_of(struct hashmap *_map_); _Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_); -struct cmc_string hm_to_string(struct hashmap *_map_); -_Bool hm_print(struct hashmap *_map_, FILE *fptr); +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); +struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void hm_release(struct hashmap _map_); +struct hashmap_iter +{ + struct hashmap *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; struct hashmap_iter hm_iter_start(struct hashmap *target); struct hashmap_iter hm_iter_end(struct hashmap *target); _Bool hm_iter_at_start(struct hashmap_iter *iter); @@ -91,6 +92,9 @@ size_t hm_iter_key(struct hashmap_iter *iter); size_t hm_iter_value(struct hashmap_iter *iter); size_t *hm_iter_rvalue(struct hashmap_iter *iter); size_t hm_iter_index(struct hashmap_iter *iter); +_Bool hm_to_string(struct hashmap *_map_, FILE *fptr); +_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key); static size_t hm_impl_calculate_size(size_t required); struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) @@ -100,6 +104,7 @@ struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -125,7 +130,7 @@ struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; return _map_; } void hm_clear(struct hashmap *_map_) @@ -167,31 +172,14 @@ void hm_free(struct hashmap *_map_) _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } -void hm_release(struct hashmap _map_) -{ - if (_map_.f_key->free || _map_.f_val->free) - { - for (size_t i = 0; i < _map_.capacity; i++) - { - struct hashmap_entry *entry = &(_map_.buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (_map_.f_key->free) - _map_.f_key->free(entry->key); - if (_map_.f_val->free) - _map_.f_val->free(entry->value); - } - } - } - _map_.alloc->free(_map_.buffer); -} void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) @@ -247,8 +235,9 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) } _map_->count++; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->create) - _map_->callbacks->create(); + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; return 1; } _Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value) @@ -268,8 +257,9 @@ _Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old *old_value = entry->value; entry->value = new_value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) @@ -293,8 +283,9 @@ _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) result->state = CMC_ES_DELETED; _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) @@ -304,26 +295,36 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - struct hashmap_iter iter = hm_iter_start(_map_); - size_t max_key = hm_iter_key(&iter); - size_t max_val = hm_iter_value(&iter); - hm_iter_next(&iter); - for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) + size_t max_key; + size_t max_val; + size_t first = 0; + for (; first < _map_->capacity; first++) { - size_t iter_key = hm_iter_key(&iter); - size_t iter_val = hm_iter_value(&iter); - if (_map_->f_key->cmp(iter_key, max_key) > 0) + if (_map_->buffer[first].state == CMC_ES_FILLED) { - max_key = iter_key; - max_val = iter_val; + max_key = _map_->buffer[first].key; + max_val = _map_->buffer[first].value; + break; + } + } + for (size_t i = first + 1; i < _map_->capacity; i++) + { + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) + { + max_key = _map_->buffer[i].key; + max_val = _map_->buffer[i].value; + } } } if (key) *key = max_key; if (value) *value = max_val; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) @@ -333,26 +334,36 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - struct hashmap_iter iter = hm_iter_start(_map_); - size_t min_key = hm_iter_key(&iter); - size_t min_val = hm_iter_value(&iter); - hm_iter_next(&iter); - for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) + size_t min_key; + size_t min_val; + size_t first = 0; + for (; first < _map_->capacity; first++) { - size_t iter_key = hm_iter_key(&iter); - size_t iter_val = hm_iter_value(&iter); - if (_map_->f_key->cmp(iter_key, min_key) < 0) + if (_map_->buffer[first].state == CMC_ES_FILLED) { - min_key = iter_key; - min_val = iter_val; + min_key = _map_->buffer[first].key; + min_val = _map_->buffer[first].value; + break; + } + } + for (size_t i = first + 1; i < _map_->capacity; i++) + { + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) + { + min_key = _map_->buffer[i].key; + min_val = _map_->buffer[i].value; + } } } if (key) *key = min_key; if (value) *value = min_val; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } size_t hm_get(struct hashmap *_map_, size_t key) @@ -369,8 +380,9 @@ size_t hm_get(struct hashmap *_map_, size_t key) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return entry->value; } size_t *hm_get_ref(struct hashmap *_map_, size_t key) @@ -387,16 +399,18 @@ size_t *hm_get_ref(struct hashmap *_map_, size_t key) return ((void *)0); } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return &(entry->value); } _Bool hm_contains(struct hashmap *_map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hm_impl_get_entry(_map_, key) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool hm_empty(struct hashmap *_map_) @@ -448,12 +462,14 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) _map_->flag = CMC_FLAG_ALLOC; return 0; } - struct hashmap_iter iter = hm_iter_start(_map_); - for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) + for (size_t i = 0; i < _map_->capacity; i++) { - size_t key = hm_iter_key(&iter); - size_t value = hm_iter_value(&iter); - hm_insert(_new_map_, key, value); + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + size_t key = _map_->buffer[i].key; + size_t value = _map_->buffer[i].value; + hm_insert(_new_map_, key, value); + } } if (_map_->count != _new_map_->count) { @@ -471,19 +487,21 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity) _new_map_->f_val = &(struct hashmap_fval){ ((void *)0) }; hm_free(_new_map_); success: - if (_map_->callbacks && _map_->callbacks->resize) - _map_->callbacks->resize(); + if ((_map_)->callbacks && (_map_)->callbacks->resize) + (_map_)->callbacks->resize(); + ; return 1; } struct hashmap *hm_copy_of(struct hashmap *_map_) { struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, _map_->callbacks); + _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _map_->callbacks; if (_map_->f_key->cpy || _map_->f_val->cpy) { for (size_t i = 0; i < _map_->capacity; i++) @@ -522,17 +540,97 @@ _Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_) _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; - struct hashmap_iter iter = hm_iter_start(_map1_); - for (; !hm_iter_at_end(&iter); hm_iter_next(&iter)) + struct hashmap *_map_a_; + struct hashmap *_map_b_; + _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; + _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; + for (size_t i = 0; i < _map_a_->capacity; i++) { - struct hashmap_entry *entry = hm_impl_get_entry(_map2_, hm_iter_key(&iter)); - if (entry == ((void *)0)) - return 0; - if (_map1_->f_val->cmp(entry->value, hm_iter_value(&iter)) != 0) - return 0; + if (_map_a_->buffer[i].state == CMC_ES_FILLED) + { + struct hashmap_entry *entry_a = &(_map_a_->buffer[i]); + struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key); + if (!entry_b) + return 0; + if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) + return 0; + } } return 1; } +static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + size_t pos = hash % _map_->capacity; + struct hashmap_entry *target = &(_map_->buffer[pos]); + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) + { + if (_map_->f_key->cmp(target->key, key) == 0) + return target; + pos++; + target = &(_map_->buffer[pos % _map_->capacity]); + } + return ((void *)0); +} +static size_t hm_impl_calculate_size(size_t required) +{ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; +} +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) +{ + return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); +} +struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + struct hashmap _map_ = { 0 }; + if (capacity == 0 || load <= 0 || load >= 1) + return _map_; + if (capacity >= 0xffffffffffffffffULL * load) + return _map_; + if (!f_key || !f_val) + return _map_; + size_t real_capacity = hm_impl_calculate_size(capacity / load); + if (!alloc) + alloc = &cmc_alloc_node_default; + _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_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_; +} +void hm_release(struct hashmap _map_) +{ + if (_map_.f_key->free || _map_.f_val->free) + { + for (size_t i = 0; i < _map_.capacity; i++) + { + struct hashmap_entry *entry = &(_map_.buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (_map_.f_key->free) + _map_.f_key->free(entry->key); + if (_map_.f_val->free) + _map_.f_val->free(entry->value); + } + } + } + _map_.alloc->free(_map_.buffer); +} struct hashmap_iter hm_iter_start(struct hashmap *target) { struct hashmap_iter iter; @@ -734,29 +832,57 @@ size_t hm_iter_index(struct hashmap_iter *iter) { return iter->index; } -static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key) +_Bool hm_to_string(struct hashmap *_map_, FILE *fptr) { - size_t hash = _map_->f_key->hash(key); - size_t pos = hash % _map_->capacity; - struct hashmap_entry *target = &(_map_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) - { - if (_map_->f_key->cmp(target->key, key) == 0) - return target; - pos++; - target = &(_map_->buffer[pos % _map_->capacity]); - } - return ((void *)0); + struct hashmap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } -static size_t hm_impl_calculate_size(size_t required) +_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) { - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; + 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 hashmap_entry *entry = &(_map_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_map_->f_key->str(fptr, entry->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HASHMAP */ diff --git a/tests/main/src/hashmultimap.c b/tests/main/src/hashmultimap.c index 981f107..0813264 100644 --- a/tests/main/src/hashmultimap.c +++ b/tests/main/src/hashmultimap.c @@ -40,17 +40,6 @@ struct hashmultimap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct hashmultimap_iter -{ - struct hashmultimap *target; - struct hashmultimap_entry *curr_entry; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, struct hashmultimap_fval *f_val); struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, @@ -79,8 +68,17 @@ int hmm_flag(struct hashmultimap *_map_); _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity); struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_); _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_); -struct cmc_string hmm_to_string(struct hashmultimap *_map_); -_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr); +struct hashmultimap_iter +{ + struct hashmultimap *target; + struct hashmultimap_entry *curr_entry; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target); struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target); _Bool hmm_iter_at_start(struct hashmultimap_iter *iter); @@ -96,6 +94,9 @@ size_t hmm_iter_key(struct hashmultimap_iter *iter); size_t hmm_iter_value(struct hashmultimap_iter *iter); size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter); size_t hmm_iter_index(struct hashmultimap_iter *iter); +_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr); +_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value); struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key); size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key); @@ -103,37 +104,13 @@ size_t hmm_impl_calculate_size(size_t required); struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, struct hashmultimap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hmm_impl_calculate_size(capacity / load); - struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); - if (!_map_->buffer) - { - alloc->free(_map_); - return ((void *)0); - } - _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 = ((void *)0); - return _map_; + return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -159,7 +136,7 @@ struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmul _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; return _map_; } void hmm_clear(struct hashmultimap *_map_) @@ -219,11 +196,12 @@ void hmm_free(struct hashmultimap *_map_) } void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) @@ -249,8 +227,9 @@ _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) } _map_->count++; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->create) - _map_->callbacks->create(); + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; return 1; } _Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value) @@ -270,8 +249,9 @@ _Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_ *old_value = entry->value; entry->value = new_value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values) @@ -316,8 +296,9 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, entry = entry->next; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return index; } _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) @@ -383,8 +364,9 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) _map_->alloc->free(entry); _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values) @@ -455,8 +437,9 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_value } _map_->count -= index; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return index; } _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) @@ -490,8 +473,9 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) if (value) *value = max_val; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) @@ -525,8 +509,9 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) if (value) *value = min_val; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } size_t hmm_get(struct hashmultimap *_map_, size_t key) @@ -543,8 +528,9 @@ size_t hmm_get(struct hashmultimap *_map_, size_t key) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return entry->value; } size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) @@ -561,16 +547,18 @@ size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) return ((void *)0); } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return &(entry->value); } _Bool hmm_contains(struct hashmultimap *_map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool hmm_empty(struct hashmultimap *_map_) @@ -649,8 +637,9 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) _new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) }; hmm_free(_new_map_); success: - if (_map_->callbacks && _map_->callbacks->resize) - _map_->callbacks->resize(); + if ((_map_)->callbacks && (_map_)->callbacks->resize) + (_map_)->callbacks->resize(); + ; return 1; } struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) @@ -676,7 +665,7 @@ struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) hmm_insert(result, key, value); } } - result->callbacks = _map_->callbacks; + (result)->callbacks = _map_->callbacks; _map_->flag = CMC_FLAG_OK; return result; } @@ -695,6 +684,54 @@ _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_) } return 1; } +struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value) +{ + struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); + if (!entry) + return ((void *)0); + entry->key = key; + entry->value = value; + entry->next = ((void *)0); + entry->prev = ((void *)0); + return entry; +} +struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; + while (entry != ((void *)0)) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + return entry; + entry = entry->next; + } + return ((void *)0); +} +size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; + size_t total_count = 0; + if (!entry) + return total_count; + while (entry != ((void *)0)) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + total_count++; + entry = entry->next; + } + return total_count; +} +size_t hmm_impl_calculate_size(size_t required) +{ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; +} struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) { struct hashmultimap_iter iter; @@ -710,7 +747,8 @@ struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) { for (size_t i = 0; i < target->capacity; i++) { - if (target->buffer[i][0] != ((void *)0)) + struct hashmultimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) { iter.curr_entry = target->buffer[i][0]; iter.first = i; @@ -720,7 +758,8 @@ struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) iter.cursor = iter.first; for (size_t i = target->capacity; i > 0; i--) { - if (target->buffer[i - 1][1] != ((void *)0)) + struct hashmultimap_entry *entry = target->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) { iter.last = i - 1; break; @@ -744,7 +783,8 @@ struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target) { for (size_t i = 0; i < target->capacity; i++) { - if (target->buffer[i][0] != ((void *)0)) + struct hashmultimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) { iter.first = i; break; @@ -752,7 +792,8 @@ struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target) } for (size_t i = target->capacity; i > 0; i--) { - if (target->buffer[i - 1][1] != ((void *)0)) + struct hashmultimap_entry *entry = target->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) { iter.curr_entry = target->buffer[i - 1][1]; iter.last = i - 1; @@ -910,53 +951,59 @@ size_t hmm_iter_index(struct hashmultimap_iter *iter) { return iter->index; } -struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value) +_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr) { - struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); - if (!entry) - return ((void *)0); - entry->key = key; - entry->value = value; - entry->next = ((void *)0); - entry->prev = ((void *)0); - return entry; + struct hashmultimap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } -struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key) +_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) { - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - while (entry != ((void *)0)) + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _map_->capacity; i > 0; i--) { - if (_map_->f_key->cmp(entry->key, key) == 0) - return entry; - entry = entry->next; + struct hashmultimap_entry *entry = _map_->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) + { + last = i - 1; + break; + } } - return ((void *)0); -} -size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - size_t total_count = 0; - if (!entry) - return total_count; - while (entry != ((void *)0)) + for (size_t i = 0; i < _map_->capacity; i++) { - if (_map_->f_key->cmp(entry->key, key) == 0) - total_count++; - entry = entry->next; + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan != ((void *)0)) + { + if (!_map_->f_key->str(fptr, scan->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, scan->value)) + return 0; + scan = scan->next; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } } - return total_count; -} -size_t hmm_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HASHMULTIMAP */ diff --git a/tests/main/src/hashmultiset.c b/tests/main/src/hashmultiset.c index b87f565..ff0c2a7 100644 --- a/tests/main/src/hashmultiset.c +++ b/tests/main/src/hashmultiset.c @@ -31,16 +31,6 @@ struct hashmultiset_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct hashmultiset_iter -{ - struct hashmultiset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val); struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -66,18 +56,16 @@ int hms_flag(struct hashmultiset *_set_); _Bool hms_resize(struct hashmultiset *_set_, size_t capacity); struct hashmultiset *hms_copy_of(struct hashmultiset *_set_); _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct cmc_string hms_to_string(struct hashmultiset *_set_); -_Bool hms_print(struct hashmultiset *_set_, FILE *fptr); -struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset_iter +{ + struct hashmultiset *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; struct hashmultiset_iter hms_iter_start(struct hashmultiset *target); struct hashmultiset_iter hms_iter_end(struct hashmultiset *target); _Bool hms_iter_at_start(struct hashmultiset_iter *iter); @@ -92,42 +80,31 @@ _Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index); size_t hms_iter_value(struct hashmultiset_iter *iter); size_t hms_iter_multiplicity(struct hashmultiset_iter *iter); size_t hms_iter_index(struct hashmultiset_iter *iter); +struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr); +_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value); static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node); static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value); static size_t hms_impl_calculate_size(size_t required); struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_val) - return ((void *)0); - size_t real_capacity = hms_impl_calculate_size(capacity / load); - struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); - if (!_set_) - return ((void *)0); - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); - if (!_set_->buffer) - { - alloc->free(_set_); - return ((void *)0); - } - _set_->count = 0; - _set_->cardinality = 0; - _set_->capacity = real_capacity; - _set_->load = load; - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - _set_->callbacks = ((void *)0); - return _set_; + return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); } struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -153,7 +130,7 @@ struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmul _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; return _set_; } void hms_clear(struct hashmultiset *_set_) @@ -191,11 +168,12 @@ void hms_free(struct hashmultiset *_set_) } void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool hms_insert(struct hashmultiset *_set_, size_t value) @@ -211,8 +189,9 @@ _Bool hms_insert(struct hashmultiset *_set_, size_t value) entry->multiplicity++; _set_->cardinality++; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->create) - _set_->callbacks->create(); + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; return 1; } _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count) @@ -233,8 +212,9 @@ _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count) _set_->cardinality += count; success: _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->create) - _set_->callbacks->create(); + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; return 1; } _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) @@ -262,8 +242,9 @@ _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) entry->multiplicity = multiplicity; success: _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->update) - _set_->callbacks->update(); + if ((_set_)->callbacks && (_set_)->callbacks->update) + (_set_)->callbacks->update(); + ; return 1; } _Bool hms_remove(struct hashmultiset *_set_, size_t value) @@ -291,8 +272,9 @@ _Bool hms_remove(struct hashmultiset *_set_, size_t value) } _set_->cardinality--; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->delete) - _set_->callbacks->delete (); + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; return 1; } size_t hms_remove_all(struct hashmultiset *_set_, size_t value) @@ -316,8 +298,9 @@ size_t hms_remove_all(struct hashmultiset *_set_, size_t value) _set_->count--; _set_->cardinality -= removed; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->delete) - _set_->callbacks->delete (); + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; return removed; } _Bool hms_max(struct hashmultiset *_set_, size_t *value) @@ -341,8 +324,9 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value) if (value) *value = max_val; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool hms_min(struct hashmultiset *_set_, size_t *value) @@ -366,16 +350,18 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value) if (value) *value = min_val; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value) { struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; if (!entry) return 0; return entry->multiplicity; @@ -384,8 +370,9 @@ _Bool hms_contains(struct hashmultiset *_set_, size_t value) { _set_->flag = CMC_FLAG_OK; _Bool result = hms_impl_get_entry(_set_, value) != ((void *)0); - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return result; } _Bool hms_empty(struct hashmultiset *_set_) @@ -460,19 +447,21 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity) _new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) }; hms_free(_new_set_); success: - if (_set_->callbacks && _set_->callbacks->resize) - _set_->callbacks->resize(); + if ((_set_)->callbacks && (_set_)->callbacks->resize) + (_set_)->callbacks->resize(); + ; return 1; } struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) { struct hashmultiset *result = - hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, _set_->callbacks); + hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _set_->callbacks; if (_set_->f_val->cpy) { for (size_t i = 0; i < _set_->capacity; i++) @@ -521,186 +510,97 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) } return 1; } -struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) { - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - size_t value = hms_iter_value(&iter1); - size_t m1 = hms_iter_multiplicity(&iter1); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - size_t max_ = m1 > m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - size_t value = hms_iter_value(&iter2); - size_t m1 = hms_impl_multiplicity_of(_set1_, value); - size_t m2 = hms_iter_multiplicity(&iter2); - size_t max_ = m1 > m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; + struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); + if (!entry) + return 0; + return entry->multiplicity; } -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) { - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct hashmultiset_iter iter = hms_iter_start(_set_A_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + *new_node = 0; + struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); + if (entry != ((void *)0)) + return entry; + *new_node = 1; + if (hms_full(_set_)) { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set_B_, value); - size_t max_ = m1 < m2 ? m1 : m2; - hms_update(_set_r_, value, max_); + if (!hms_resize(_set_, _set_->capacity + 1)) + return ((void *)0); } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + size_t hash = _set_->f_val->hash(value); + size_t original_pos = hash % _set_->capacity; + size_t pos = original_pos; + size_t curr_mul = 1; + struct hashmultiset_entry *target = &(_set_->buffer[pos]); + struct hashmultiset_entry *to_return = ((void *)0); + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); + target->value = value; + target->multiplicity = curr_mul; + target->dist = pos - original_pos; + target->state = CMC_ES_FILLED; + to_return = target; } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + else { - hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - size_t value = hms_iter_value(&iter1); - size_t m1 = hms_iter_multiplicity(&iter1); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 != m2) + while (1) { - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - else - hms_update(_set_r_, value, m2 - m1); + pos++; + target = &(_set_->buffer[pos % _set_->capacity]); + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) + { + target->value = value; + target->multiplicity = curr_mul; + target->dist = pos - original_pos; + target->state = CMC_ES_FILLED; + if (!to_return) + to_return = target; + break; + } + else if (target->dist < pos - original_pos) + { + size_t tmp = target->value; + size_t tmp_dist = target->dist; + size_t tmp_mul = target->multiplicity; + target->value = value; + target->dist = pos - original_pos; + target->multiplicity = curr_mul; + value = tmp; + original_pos = pos - tmp_dist; + curr_mul = tmp_mul; + if (!to_return) + to_return = target; + } } } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - size_t value = hms_iter_value(&iter2); - size_t m1 = hms_impl_multiplicity_of(_set1_, value); - size_t m2 = hms_iter_multiplicity(&iter2); - if (m1 != m2) - { - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - else - hms_update(_set_r_, value, m2 - m1); - } - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; + _set_->count++; + return to_return; } -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value) { - if (_set1_->count > _set2_->count) - return 0; - if (hms_empty(_set1_)) - return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + size_t hash = _set_->f_val->hash(value); + size_t pos = hash % _set_->capacity; + struct hashmultiset_entry *target = &(_set_->buffer[pos]); + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 > m2) - return 0; + if (_set_->f_val->cmp(target->value, value) == 0) + return target; + pos++; + target = &(_set_->buffer[pos % _set_->capacity]); } - return 1; + return ((void *)0); } -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +static size_t hms_impl_calculate_size(size_t required) { - return hms_is_subset(_set2_, _set1_); -} -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (_set1_->count >= _set2_->count) - return 0; - if (hms_empty(_set1_)) - { - if (!hms_empty(_set2_)) - return 1; - else - return 0; - } - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 >= m2) - return 0; - } - return 1; -} -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - return hms_is_proper_subset(_set2_, _set1_); -} -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (hms_empty(_set1_)) - return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - if (hms_impl_get_entry(_set2_, value) != ((void *)0)) - return 0; - } - return 1; + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; } struct hashmultiset_iter hms_iter_start(struct hashmultiset *target) { @@ -897,97 +797,244 @@ size_t hms_iter_index(struct hashmultiset_iter *iter) { return iter->index; } -static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) +struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - if (!entry) - return 0; - return entry->multiplicity; + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + { + size_t value = hms_iter_value(&iter1); + size_t m1 = hms_iter_multiplicity(&iter1); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + size_t max_ = m1 > m2 ? m1 : m2; + hms_update(_set_r_, value, max_); + } + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) + { + size_t value = hms_iter_value(&iter2); + size_t m1 = hms_impl_multiplicity_of(_set1_, value); + size_t m2 = hms_iter_multiplicity(&iter2); + size_t max_ = m1 > m2 ? m1 : m2; + hms_update(_set_r_, value, max_); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; } -static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) +struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { - *new_node = 0; - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - if (entry != ((void *)0)) - return entry; - *new_node = 1; - if (hms_full(_set_)) + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct hashmultiset_iter iter = hms_iter_start(_set_A_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { - if (!hms_resize(_set_, _set_->capacity + 1)) - return ((void *)0); + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set_B_, value); + size_t max_ = m1 < m2 ? m1 : m2; + hms_update(_set_r_, value, max_); } - size_t hash = _set_->f_val->hash(value); - size_t original_pos = hash % _set_->capacity; - size_t pos = original_pos; - size_t curr_mul = 1; - struct hashmultiset_entry *target = &(_set_->buffer[pos]); - struct hashmultiset_entry *to_return = ((void *)0); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { - target->value = value; - target->multiplicity = curr_mul; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - to_return = target; + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); } - else + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { - while (1) + hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); + } + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) + { + hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + { + size_t value = hms_iter_value(&iter1); + size_t m1 = hms_iter_multiplicity(&iter1); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 != m2) { - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->value = value; - target->multiplicity = curr_mul; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - if (!to_return) - to_return = target; - break; - } - else if (target->dist < pos - original_pos) - { - size_t tmp = target->value; - size_t tmp_dist = target->dist; - size_t tmp_mul = target->multiplicity; - target->value = value; - target->dist = pos - original_pos; - target->multiplicity = curr_mul; - value = tmp; - original_pos = pos - tmp_dist; - curr_mul = tmp_mul; - if (!to_return) - to_return = target; - } + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); + else + hms_update(_set_r_, value, m2 - m1); } } - _set_->count++; - return to_return; -} -static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value) -{ - size_t hash = _set_->f_val->hash(value); - size_t pos = hash % _set_->capacity; - struct hashmultiset_entry *target = &(_set_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { - if (_set_->f_val->cmp(target->value, value) == 0) - return target; - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); + size_t value = hms_iter_value(&iter2); + size_t m1 = hms_impl_multiplicity_of(_set1_, value); + size_t m2 = hms_iter_multiplicity(&iter2); + if (m1 != m2) + { + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); + else + hms_update(_set_r_, value, m2 - m1); + } } - return ((void *)0); + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; } -static size_t hms_impl_calculate_size(size_t required) +_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) { - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; + if (_set1_->count > _set2_->count) + return 0; + if (hms_empty(_set1_)) + return 1; + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 > m2) + return 0; + } + return 1; +} +_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + return hms_is_subset(_set2_, _set1_); +} +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + if (_set1_->count >= _set2_->count) + return 0; + if (hms_empty(_set1_)) + { + if (!hms_empty(_set2_)) + return 1; + else + return 0; + } + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 >= m2) + return 0; + } + return 1; +} +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + return hms_is_proper_subset(_set2_, _set1_); +} +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + if (hms_empty(_set1_)) + return 1; + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + if (hms_impl_get_entry(_set2_, value) != ((void *)0)) + return 0; + } + return 1; +} +_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr) +{ + struct hashmultiset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "cardinality:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load, + s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); +} +_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *val_mul_sep) +{ + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _set_->capacity; i > 0; i--) + { + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashmultiset_entry *entry = &(_set_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_set_->f_val->str(fptr, entry->value)) + return 0; + fprintf(fptr, "%s", val_mul_sep); + if (fprintf(fptr, + "%" + "I64u" + "", + entry->multiplicity) < 0) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HASHMULTISET */ diff --git a/tests/main/src/hashset.c b/tests/main/src/hashset.c index f4b278f..cf11adb 100644 --- a/tests/main/src/hashset.c +++ b/tests/main/src/hashset.c @@ -29,16 +29,6 @@ struct hashset_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct hashset_iter -{ - struct hashset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val); struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -59,17 +49,16 @@ int hs_flag(struct hashset *_set_); _Bool hs_resize(struct hashset *_set_, size_t capacity); struct hashset *hs_copy_of(struct hashset *_set_); _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_); -struct cmc_string hs_to_string(struct hashset *_set_); -_Bool hs_print(struct hashset *_set_, FILE *fptr); -struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); +struct hashset_iter +{ + struct hashset *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; struct hashset_iter hs_iter_start(struct hashset *target); struct hashset_iter hs_iter_end(struct hashset *target); _Bool hs_iter_at_start(struct hashset_iter *iter); @@ -83,41 +72,27 @@ _Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps); _Bool hs_iter_go_to(struct hashset_iter *iter, size_t index); size_t hs_iter_value(struct hashset_iter *iter); size_t hs_iter_index(struct hashset_iter *iter); +struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_to_string(struct hashset *_set_, FILE *fptr); +_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value); static size_t hs_impl_calculate_size(size_t required); -static struct hashset_iter hs_impl_it_start(struct hashset *_set_); -static struct hashset_iter hs_impl_it_end(struct hashset *_set_); struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_val) - return ((void *)0); - size_t real_capacity = hs_impl_calculate_size(capacity / load); - struct hashset *_set_ = alloc->malloc(sizeof(struct hashset)); - if (!_set_) - return ((void *)0); - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry)); - if (!_set_->buffer) - { - alloc->free(_set_); - return ((void *)0); - } - _set_->count = 0; - _set_->capacity = real_capacity; - _set_->load = load; - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - _set_->callbacks = ((void *)0); - return _set_; + return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); } struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) @@ -142,7 +117,7 @@ struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; return _set_; } void hs_clear(struct hashset *_set_) @@ -180,11 +155,12 @@ void hs_free(struct hashset *_set_) } void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool hs_insert(struct hashset *_set_, size_t value) @@ -235,8 +211,9 @@ _Bool hs_insert(struct hashset *_set_, size_t value) } _set_->count++; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->create) - _set_->callbacks->create(); + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; return 1; } _Bool hs_remove(struct hashset *_set_, size_t value) @@ -257,8 +234,9 @@ _Bool hs_remove(struct hashset *_set_, size_t value) result->state = CMC_ES_DELETED; _set_->count--; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->delete) - _set_->callbacks->delete (); + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; return 1; } _Bool hs_max(struct hashset *_set_, size_t *value) @@ -282,8 +260,9 @@ _Bool hs_max(struct hashset *_set_, size_t *value) if (value) *value = max_value; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool hs_min(struct hashset *_set_, size_t *value) @@ -307,16 +286,18 @@ _Bool hs_min(struct hashset *_set_, size_t *value) if (value) *value = min_value; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool hs_contains(struct hashset *_set_, size_t value) { _set_->flag = CMC_FLAG_OK; _Bool result = hs_impl_get_entry(_set_, value) != ((void *)0); - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return result; } _Bool hs_empty(struct hashset *_set_) @@ -388,19 +369,21 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity) _new_set_->f_val = &(struct hashset_fval){ ((void *)0) }; hs_free(_new_set_); success: - if (_set_->callbacks && _set_->callbacks->resize) - _set_->callbacks->resize(); + if ((_set_)->callbacks && (_set_)->callbacks->resize) + (_set_)->callbacks->resize(); + ; return 1; } struct hashset *hs_copy_of(struct hashset *_set_) { struct hashset *result = - hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, _set_->callbacks); + hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _set_->callbacks; if (_set_->f_val->cpy) { for (size_t i = 0; i < _set_->capacity; i++) @@ -442,155 +425,29 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) } return 1; } -struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) +static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value) { - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) + size_t hash = _set_->f_val->hash(value); + size_t pos = hash % _set_->capacity; + struct hashset_entry *target = &(_set_->buffer[pos]); + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); + if (_set_->f_val->cmp(target->value, value) == 0) + return target; + pos++; + target = &(_set_->buffer[pos % _set_->capacity]); } - struct hashset_iter iter1 = hs_iter_start(_set1_); - struct hashset_iter iter2 = hs_iter_start(_set2_); - for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) - { - hs_insert(_set_r_, hs_iter_value(&iter1)); - } - for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) - { - hs_insert(_set_r_, hs_iter_value(&iter2)); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; + return ((void *)0); } -struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_) +static size_t hs_impl_calculate_size(size_t required) { - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct hashset_iter iter = hs_iter_start(_set_A_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) - hs_insert(_set_r_, value); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter1 = hs_iter_start(_set1_); - struct hashset_iter iter2 = hs_iter_start(_set2_); - for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) - { - size_t value = hs_iter_value(&iter1); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) - { - size_t value = hs_iter_value(&iter2); - if (hs_impl_get_entry(_set1_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - _set_r_->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count > _set2_->count) - return 0; - if (hs_empty(_set1_)) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_) -{ - return hs_is_subset(_set2_, _set1_); -} -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count >= _set2_->count) - return 0; - if (hs_empty(_set1_)) - { - if (!hs_empty(_set2_)) - return 1; - else - return 0; - } - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_) -{ - return hs_is_proper_subset(_set2_, _set1_); -} -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (hs_empty(_set1_)) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) != ((void *)0)) - return 0; - } - return 1; + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; } struct hashset_iter hs_iter_start(struct hashset *target) { @@ -781,29 +638,202 @@ size_t hs_iter_index(struct hashset_iter *iter) { return iter->index; } -static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value) +struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) { - size_t hash = _set_->f_val->hash(value); - size_t pos = hash % _set_->capacity; - struct hashset_entry *target = &(_set_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) { - if (_set_->f_val->cmp(target->value, value) == 0) - return target; - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); } - return ((void *)0); + struct hashset_iter iter1 = hs_iter_start(_set1_); + struct hashset_iter iter2 = hs_iter_start(_set2_); + for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) + { + hs_insert(_set_r_, hs_iter_value(&iter1)); + } + for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) + { + hs_insert(_set_r_, hs_iter_value(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; } -static size_t hs_impl_calculate_size(size_t required) +struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_) { - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct hashset_iter iter = hs_iter_start(_set_A_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) +{ + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_) +{ + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset_iter iter1 = hs_iter_start(_set1_); + struct hashset_iter iter2 = hs_iter_start(_set2_); + for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) + { + size_t value = hs_iter_value(&iter1); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) + { + size_t value = hs_iter_value(&iter2); + if (hs_impl_get_entry(_set1_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count > _set2_->count) + return 0; + if (hs_empty(_set1_)) + return 1; + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_) +{ + return hs_is_subset(_set2_, _set1_); +} +_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count >= _set2_->count) + return 0; + if (hs_empty(_set1_)) + { + if (!hs_empty(_set2_)) + return 1; + else + return 0; + } + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_) +{ + return hs_is_proper_subset(_set2_, _set1_); +} +_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (hs_empty(_set1_)) + return 1; + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) != ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_to_string(struct hashset *_set_, FILE *fptr) +{ + struct hashset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p }", + "hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, + s_->alloc, (s_)->callbacks); +} +_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _set_->capacity; i > 0; i--) + { + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashset_entry *entry = &(_set_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_set_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HASHSET */ diff --git a/tests/main/src/heap.c b/tests/main/src/heap.c index 37b968d..5e435b9 100644 --- a/tests/main/src/heap.c +++ b/tests/main/src/heap.c @@ -23,13 +23,6 @@ struct heap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct heap_iter -{ - struct heap *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val); struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -48,8 +41,13 @@ int h_flag(struct heap *_heap_); _Bool h_resize(struct heap *_heap_, size_t capacity); struct heap *h_copy_of(struct heap *_heap_); _Bool h_equals(struct heap *_heap1_, struct heap *_heap2_); -struct cmc_string h_to_string(struct heap *_heap_); -_Bool h_print(struct heap *_heap_, FILE *fptr); +struct heap_iter +{ + struct heap *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct heap_iter h_iter_start(struct heap *target); struct heap_iter h_iter_end(struct heap *target); _Bool h_iter_at_start(struct heap_iter *iter); @@ -63,38 +61,18 @@ _Bool h_iter_rewind(struct heap_iter *iter, size_t steps); _Bool h_iter_go_to(struct heap_iter *iter, size_t index); size_t h_iter_value(struct heap_iter *iter); size_t h_iter_index(struct heap_iter *iter); +_Bool h_to_string(struct heap *_heap_, FILE *fptr); +_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); static void h_impl_float_up(struct heap *_heap_, size_t index); static void h_impl_float_down(struct heap *_heap_, size_t index); struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct heap *_heap_ = alloc->malloc(sizeof(struct heap)); - if (!_heap_) - return ((void *)0); - _heap_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_heap_->buffer) - { - alloc->free(_heap_); - return ((void *)0); - } - _heap_->capacity = capacity; - _heap_->count = 0; - _heap_->HO = HO; - _heap_->flag = CMC_FLAG_OK; - _heap_->f_val = f_val; - _heap_->alloc = alloc; - _heap_->callbacks = ((void *)0); - return _heap_; + return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0)); } struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) @@ -118,7 +96,7 @@ struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_f _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; - _heap_->callbacks = callbacks; + (_heap_)->callbacks = callbacks; return _heap_; } void h_clear(struct heap *_heap_) @@ -148,11 +126,12 @@ void h_free(struct heap *_heap_) } void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _heap_->alloc = &cmc_alloc_node_default; else _heap_->alloc = alloc; - _heap_->callbacks = callbacks; + (_heap_)->callbacks = callbacks; _heap_->flag = CMC_FLAG_OK; } _Bool h_insert(struct heap *_heap_, size_t value) @@ -168,8 +147,9 @@ _Bool h_insert(struct heap *_heap_, size_t value) h_impl_float_up(_heap_, _heap_->count - 1); } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->create) - _heap_->callbacks->create(); + if ((_heap_)->callbacks && (_heap_)->callbacks->create) + (_heap_)->callbacks->create(); + ; return 1; } _Bool h_remove(struct heap *_heap_) @@ -184,8 +164,9 @@ _Bool h_remove(struct heap *_heap_) _heap_->count--; h_impl_float_down(_heap_, 0); _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->delete) - _heap_->callbacks->delete (); + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; return 1; } size_t h_peek(struct heap *_heap_) @@ -196,8 +177,9 @@ size_t h_peek(struct heap *_heap_) return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; return _heap_->buffer[0]; } _Bool h_contains(struct heap *_heap_, size_t value) @@ -212,8 +194,9 @@ _Bool h_contains(struct heap *_heap_, size_t value) break; } } - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; return result; } _Bool h_empty(struct heap *_heap_) @@ -255,18 +238,20 @@ _Bool h_resize(struct heap *_heap_, size_t capacity) _heap_->buffer = new_buffer; _heap_->capacity = capacity; success: - if (_heap_->callbacks && _heap_->callbacks->resize) - _heap_->callbacks->resize(); + if ((_heap_)->callbacks && (_heap_)->callbacks->resize) + (_heap_)->callbacks->resize(); + ; return 1; } struct heap *h_copy_of(struct heap *_heap_) { - struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, _heap_->callbacks); + struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0)); if (!result) { _heap_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _heap_->callbacks; if (_heap_->f_val->cpy) { for (size_t i = 0; i < _heap_->count; i++) @@ -291,6 +276,51 @@ _Bool h_equals(struct heap *_heap1_, struct heap *_heap2_) } return 1; } +static void h_impl_float_up(struct heap *_heap_, size_t index) +{ + size_t C = index; + size_t child = _heap_->buffer[C]; + size_t parent = _heap_->buffer[(index - 1) / 2]; + int mod = _heap_->HO; + while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) + { + size_t tmp = _heap_->buffer[C]; + _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; + _heap_->buffer[(C - 1) / 2] = tmp; + C = (C - 1) / 2; + if (C == 0) + break; + child = _heap_->buffer[C]; + parent = _heap_->buffer[(C - 1) / 2]; + } +} +static void h_impl_float_down(struct heap *_heap_, size_t index) +{ + int mod = _heap_->HO; + while (index < _heap_->count) + { + size_t L = 2 * index + 1; + size_t R = 2 * index + 2; + size_t C = index; + if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) + { + C = L; + } + if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) + { + C = R; + } + if (C != index) + { + size_t tmp = _heap_->buffer[index]; + _heap_->buffer[index] = _heap_->buffer[C]; + _heap_->buffer[C] = tmp; + index = C; + } + else + break; + } +} struct heap_iter h_iter_start(struct heap *target) { struct heap_iter iter; @@ -419,50 +449,40 @@ size_t h_iter_index(struct heap_iter *iter) { return iter->cursor; } -static void h_impl_float_up(struct heap *_heap_, size_t index) +_Bool h_to_string(struct heap *_heap_, FILE *fptr) { - size_t C = index; - size_t child = _heap_->buffer[C]; - size_t parent = _heap_->buffer[(index - 1) / 2]; - int mod = _heap_->HO; - while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) - { - size_t tmp = _heap_->buffer[C]; - _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; - _heap_->buffer[(C - 1) / 2] = tmp; - C = (C - 1) / 2; - if (C == 0) - break; - child = _heap_->buffer[C]; - parent = _heap_->buffer[(C - 1) / 2]; - } + struct heap *h_ = _heap_; + const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "type:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p}", + "heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, + (h_)->callbacks); } -static void h_impl_float_down(struct heap *_heap_, size_t index) +_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end) { - int mod = _heap_->HO; - while (index < _heap_->count) + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _heap_->count; i++) { - size_t L = 2 * index + 1; - size_t R = 2 * index + 2; - size_t C = index; - if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) - { - C = L; - } - if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) - { - C = R; - } - if (C != index) - { - size_t tmp = _heap_->buffer[index]; - _heap_->buffer[index] = _heap_->buffer[C]; - _heap_->buffer[C] = tmp; - index = C; - } - else - break; + if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) + return 0; + if (i + 1 < _heap_->count) + fprintf(fptr, "%s", separator); } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_HEAP */ diff --git a/tests/main/src/intervalheap.c b/tests/main/src/intervalheap.c index f72ad33..b609bfb 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/main/src/intervalheap.c @@ -23,13 +23,6 @@ struct intervalheap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct intervalheap_iter -{ - struct intervalheap *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val); struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -50,10 +43,15 @@ size_t ih_count(struct intervalheap *_heap_); size_t ih_capacity(struct intervalheap *_heap_); int ih_flag(struct intervalheap *_heap_); _Bool ih_resize(struct intervalheap *_heap_, size_t capacity); -struct intervalheap *ih_copy_of(struct intervalheap *_set_); +struct intervalheap *ih_copy_of(struct intervalheap *_heap_); _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_); -struct cmc_string ih_to_string(struct intervalheap *_heap_); -_Bool ih_print(struct intervalheap *_heap_, FILE *fptr); +struct intervalheap_iter +{ + struct intervalheap *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct intervalheap_iter ih_iter_start(struct intervalheap *target); struct intervalheap_iter ih_iter_end(struct intervalheap *target); _Bool ih_iter_at_start(struct intervalheap_iter *iter); @@ -67,39 +65,20 @@ _Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps); _Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index); size_t ih_iter_value(struct intervalheap_iter *iter); size_t ih_iter_index(struct intervalheap_iter *iter); +_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr); +_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); static void ih_impl_float_up_max(struct intervalheap *_heap_); static void ih_impl_float_up_min(struct intervalheap *_heap_); static void ih_impl_float_down_max(struct intervalheap *_heap_); static void ih_impl_float_down_min(struct intervalheap *_heap_); struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity == 0 || capacity == 0xffffffffffffffffULL) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap)); - if (!_heap_) - return ((void *)0); - capacity = (capacity + capacity % 2) / 2; - _heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2])); - if (!_heap_->buffer) - { - alloc->free(_heap_); - return ((void *)0); - } - _heap_->capacity = capacity; - _heap_->size = 0; - _heap_->count = 0; - _heap_->flag = CMC_FLAG_OK; - _heap_->f_val = f_val; - _heap_->alloc = alloc; - _heap_->callbacks = ((void *)0); - return _heap_; + return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity == 0 || capacity == 0xffffffffffffffffULL) return ((void *)0); if (!f_val) @@ -122,7 +101,7 @@ struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_ _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; - _heap_->callbacks = callbacks; + (_heap_)->callbacks = callbacks; return _heap_; } void ih_clear(struct intervalheap *_heap_) @@ -153,11 +132,12 @@ void ih_free(struct intervalheap *_heap_) } void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _heap_->alloc = &cmc_alloc_node_default; else _heap_->alloc = alloc; - _heap_->callbacks = callbacks; + (_heap_)->callbacks = callbacks; _heap_->flag = CMC_FLAG_OK; } _Bool ih_insert(struct intervalheap *_heap_, size_t value) @@ -196,8 +176,9 @@ _Bool ih_insert(struct intervalheap *_heap_, size_t value) else if (_heap_->f_val->cmp((*parent)[1], value) < 0) ih_impl_float_up_max(_heap_); } - if (_heap_->callbacks && _heap_->callbacks->create) - _heap_->callbacks->create(); + if ((_heap_)->callbacks && (_heap_)->callbacks->create) + (_heap_)->callbacks->create(); + ; return 1; } _Bool ih_remove_max(struct intervalheap *_heap_) @@ -230,8 +211,9 @@ _Bool ih_remove_max(struct intervalheap *_heap_) ih_impl_float_down_max(_heap_); success: _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->delete) - _heap_->callbacks->delete (); + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; return 1; } _Bool ih_remove_min(struct intervalheap *_heap_) @@ -264,8 +246,9 @@ _Bool ih_remove_min(struct intervalheap *_heap_) ih_impl_float_down_min(_heap_); success: _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->delete) - _heap_->callbacks->delete (); + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; return 1; } _Bool ih_update_max(struct intervalheap *_heap_, size_t value) @@ -291,8 +274,9 @@ _Bool ih_update_max(struct intervalheap *_heap_, size_t value) ih_impl_float_down_max(_heap_); } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->update) - _heap_->callbacks->update(); + if ((_heap_)->callbacks && (_heap_)->callbacks->update) + (_heap_)->callbacks->update(); + ; return 1; } _Bool ih_update_min(struct intervalheap *_heap_, size_t value) @@ -318,8 +302,9 @@ _Bool ih_update_min(struct intervalheap *_heap_, size_t value) ih_impl_float_down_min(_heap_); } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->update) - _heap_->callbacks->update(); + if ((_heap_)->callbacks && (_heap_)->callbacks->update) + (_heap_)->callbacks->update(); + ; return 1; } size_t ih_max(struct intervalheap *_heap_) @@ -330,8 +315,9 @@ size_t ih_max(struct intervalheap *_heap_) return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; if (_heap_->count == 1) return _heap_->buffer[0][0]; return _heap_->buffer[0][1]; @@ -344,8 +330,9 @@ size_t ih_min(struct intervalheap *_heap_) return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; return _heap_->buffer[0][0]; } _Bool ih_contains(struct intervalheap *_heap_, size_t value) @@ -360,8 +347,9 @@ _Bool ih_contains(struct intervalheap *_heap_, size_t value) break; } } - if (_heap_->callbacks && _heap_->callbacks->read) - _heap_->callbacks->read(); + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; return result; } _Bool ih_empty(struct intervalheap *_heap_) @@ -413,8 +401,9 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity) _heap_->capacity = capacity; success: _heap_->flag = CMC_FLAG_OK; - if (_heap_->callbacks && _heap_->callbacks->resize) - _heap_->callbacks->resize(); + if ((_heap_)->callbacks && (_heap_)->callbacks->resize) + (_heap_)->callbacks->resize(); + ; return 1; } struct intervalheap *ih_copy_of(struct intervalheap *_heap_) @@ -446,7 +435,7 @@ struct intervalheap *ih_copy_of(struct intervalheap *_heap_) result->flag = CMC_FLAG_OK; result->f_val = _heap_->f_val; result->alloc = _heap_->alloc; - result->callbacks = _heap_->callbacks; + (result)->callbacks = _heap_->callbacks; _heap_->flag = CMC_FLAG_OK; return result; } @@ -465,134 +454,6 @@ _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_) } return 1; } -struct intervalheap_iter ih_iter_start(struct intervalheap *target) -{ - struct intervalheap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = ih_empty(target); - return iter; -} -struct intervalheap_iter ih_iter_end(struct intervalheap *target) -{ - struct intervalheap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = ih_empty(target); - iter.end = 1; - if (!ih_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool ih_iter_at_start(struct intervalheap_iter *iter) -{ - return ih_empty(iter->target) || iter->start; -} -_Bool ih_iter_at_end(struct intervalheap_iter *iter) -{ - return ih_empty(iter->target) || iter->end; -} -_Bool ih_iter_to_start(struct intervalheap_iter *iter) -{ - if (!ih_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = ih_empty(iter->target); - return 1; - } - return 0; -} -_Bool ih_iter_to_end(struct intervalheap_iter *iter) -{ - if (!ih_empty(iter->target)) - { - iter->cursor = iter->target->count - 1; - iter->start = ih_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool ih_iter_next(struct intervalheap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = ih_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool ih_iter_prev(struct intervalheap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = ih_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - if (iter->end) - return 0; - iter->start = ih_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = ih_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return ih_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return ih_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t ih_iter_value(struct intervalheap_iter *iter) -{ - if (ih_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; -} -size_t ih_iter_index(struct intervalheap_iter *iter) -{ - return iter->cursor; -} static void ih_impl_float_up_max(struct intervalheap *_heap_) { size_t index = _heap_->size - 1; @@ -725,5 +586,169 @@ static void ih_impl_float_down_min(struct intervalheap *_heap_) curr_node = child_node; } } +struct intervalheap_iter ih_iter_start(struct intervalheap *target) +{ + struct intervalheap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = ih_empty(target); + return iter; +} +struct intervalheap_iter ih_iter_end(struct intervalheap *target) +{ + struct intervalheap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = ih_empty(target); + iter.end = 1; + if (!ih_empty(target)) + iter.cursor = target->count - 1; + return iter; +} +_Bool ih_iter_at_start(struct intervalheap_iter *iter) +{ + return ih_empty(iter->target) || iter->start; +} +_Bool ih_iter_at_end(struct intervalheap_iter *iter) +{ + return ih_empty(iter->target) || iter->end; +} +_Bool ih_iter_to_start(struct intervalheap_iter *iter) +{ + if (!ih_empty(iter->target)) + { + iter->cursor = 0; + iter->start = 1; + iter->end = ih_empty(iter->target); + return 1; + } + return 0; +} +_Bool ih_iter_to_end(struct intervalheap_iter *iter) +{ + if (!ih_empty(iter->target)) + { + iter->cursor = iter->target->count - 1; + iter->start = ih_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool ih_iter_next(struct intervalheap_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = ih_empty(iter->target); + iter->cursor++; + return 1; +} +_Bool ih_iter_prev(struct intervalheap_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + iter->end = ih_empty(iter->target); + iter->cursor--; + return 1; +} +_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return 0; + if (iter->end) + return 0; + iter->start = ih_empty(iter->target); + iter->cursor += steps; + return 1; +} +_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->cursor < steps) + return 0; + iter->end = ih_empty(iter->target); + iter->cursor -= steps; + return 1; +} +_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->cursor > index) + return ih_iter_rewind(iter, iter->cursor - index); + else if (iter->cursor < index) + return ih_iter_advance(iter, index - iter->cursor); + return 1; +} +size_t ih_iter_value(struct intervalheap_iter *iter) +{ + if (ih_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; +} +size_t ih_iter_index(struct intervalheap_iter *iter) +{ + return iter->cursor; +} +_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr) +{ + struct intervalheap *h_ = _heap_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "size:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, + h_->f_val, h_->alloc, (h_)->callbacks); +} +_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _heap_->count; i++) + { + if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) + return 0; + if (i + 1 < _heap_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_INTERVALHEAP */ diff --git a/tests/main/src/linkedlist.c b/tests/main/src/linkedlist.c index e07b066..3030f9b 100644 --- a/tests/main/src/linkedlist.c +++ b/tests/main/src/linkedlist.c @@ -28,14 +28,6 @@ struct linkedlist_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct linkedlist_iter -{ - struct linkedlist *target; - struct linkedlist_node *cursor; - size_t index; - _Bool start; - _Bool end; -}; struct linkedlist *ll_new(struct linkedlist_fval *f_val); struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -58,20 +50,14 @@ size_t ll_count(struct linkedlist *_list_); int ll_flag(struct linkedlist *_list_); struct linkedlist *ll_copy_of(struct linkedlist *_list_); _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_); -struct cmc_string ll_to_string(struct linkedlist *_list_); -_Bool ll_print(struct linkedlist *_list_, FILE *fptr); -struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); -void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_head(struct linkedlist *_list_); -struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); -struct linkedlist_node *ll_tail(struct linkedlist *_list_); -_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); -struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); +struct linkedlist_iter +{ + struct linkedlist *target; + struct linkedlist_node *cursor; + size_t index; + _Bool start; + _Bool end; +}; struct linkedlist_iter ll_iter_start(struct linkedlist *target); struct linkedlist_iter ll_iter_end(struct linkedlist *target); _Bool ll_iter_at_start(struct linkedlist_iter *iter); @@ -87,26 +73,28 @@ size_t ll_iter_value(struct linkedlist_iter *iter); size_t *ll_iter_rvalue(struct linkedlist_iter *iter); size_t ll_iter_index(struct linkedlist_iter *iter); struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter); +struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); +void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); +struct linkedlist_node *ll_head(struct linkedlist *_list_); +struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); +struct linkedlist_node *ll_tail(struct linkedlist *_list_); +_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); +_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); +_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); +struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); +struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); +_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr); +_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); struct linkedlist *ll_new(struct linkedlist_fval *f_val) { - if (!f_val) - return ((void *)0); - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist)); - if (!_list_) - return ((void *)0); - _list_->count = 0; - _list_->head = ((void *)0); - _list_->tail = ((void *)0); - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - _list_->callbacks = ((void *)0); - return _list_; + return ll_new_custom(f_val, ((void *)0), ((void *)0)); } struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!f_val) return ((void *)0); if (!alloc) @@ -120,7 +108,7 @@ struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; return _list_; } void ll_clear(struct linkedlist *_list_) @@ -148,11 +136,12 @@ void ll_free(struct linkedlist *_list_) } void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool ll_push_front(struct linkedlist *_list_, size_t value) @@ -173,8 +162,9 @@ _Bool ll_push_front(struct linkedlist *_list_, size_t value) } _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) @@ -202,8 +192,9 @@ _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) _node_->prev->next = _node_; _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool ll_push_back(struct linkedlist *_list_, size_t value) @@ -224,8 +215,9 @@ _Bool ll_push_back(struct linkedlist *_list_, size_t value) } _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool ll_pop_front(struct linkedlist *_list_) @@ -244,8 +236,9 @@ _Bool ll_pop_front(struct linkedlist *_list_) _list_->head->prev = ((void *)0); _list_->count--; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } _Bool ll_pop_at(struct linkedlist *_list_, size_t index) @@ -276,8 +269,9 @@ _Bool ll_pop_at(struct linkedlist *_list_, size_t index) _list_->alloc->free(_node_); _list_->count--; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } _Bool ll_pop_back(struct linkedlist *_list_) @@ -296,8 +290,9 @@ _Bool ll_pop_back(struct linkedlist *_list_) _list_->tail->next = ((void *)0); _list_->count--; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } size_t ll_front(struct linkedlist *_list_) @@ -308,8 +303,9 @@ size_t ll_front(struct linkedlist *_list_) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->head->value; } size_t ll_get(struct linkedlist *_list_, size_t index) @@ -327,8 +323,9 @@ size_t ll_get(struct linkedlist *_list_, size_t index) struct linkedlist_node *scan = ll_get_node(_list_, index); if (scan == ((void *)0)) return (size_t){ 0 }; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return scan->value; } size_t *ll_get_ref(struct linkedlist *_list_, size_t index) @@ -346,8 +343,9 @@ size_t *ll_get_ref(struct linkedlist *_list_, size_t index) struct linkedlist_node *scan = ll_get_node(_list_, index); if (scan == ((void *)0)) return ((void *)0); - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return &(scan->value); } size_t ll_back(struct linkedlist *_list_) @@ -358,8 +356,9 @@ size_t ll_back(struct linkedlist *_list_) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->tail->value; } _Bool ll_contains(struct linkedlist *_list_, size_t value) @@ -376,8 +375,9 @@ _Bool ll_contains(struct linkedlist *_list_, size_t value) } scan = scan->next; } - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return result; } _Bool ll_empty(struct linkedlist *_list_) @@ -394,9 +394,10 @@ int ll_flag(struct linkedlist *_list_) } struct linkedlist *ll_copy_of(struct linkedlist *_list_) { - struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks); + struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0)); if (!result) return ((void *)0); + (result)->callbacks = _list_->callbacks; struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) { @@ -439,6 +440,152 @@ _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) } return 1; } +struct linkedlist_iter ll_iter_start(struct linkedlist *target) +{ + struct linkedlist_iter iter; + iter.target = target; + iter.cursor = target->head; + iter.index = 0; + iter.start = 1; + iter.end = ll_empty(target); + return iter; +} +struct linkedlist_iter ll_iter_end(struct linkedlist *target) +{ + struct linkedlist_iter iter; + iter.target = target; + iter.cursor = target->tail; + iter.index = 0; + iter.start = ll_empty(target); + iter.end = 1; + if (!ll_empty(target)) + iter.index = target->count - 1; + return iter; +} +_Bool ll_iter_at_start(struct linkedlist_iter *iter) +{ + return ll_empty(iter->target) || iter->start; +} +_Bool ll_iter_at_end(struct linkedlist_iter *iter) +{ + return ll_empty(iter->target) || iter->end; +} +_Bool ll_iter_to_start(struct linkedlist_iter *iter) +{ + if (!ll_empty(iter->target)) + { + iter->cursor = iter->target->head; + iter->index = 0; + iter->start = 1; + iter->end = ll_empty(iter->target); + return 1; + } + return 0; +} +_Bool ll_iter_to_end(struct linkedlist_iter *iter) +{ + if (!ll_empty(iter->target)) + { + iter->cursor = iter->target->tail; + iter->index = iter->target->count - 1; + iter->start = ll_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool ll_iter_next(struct linkedlist_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor->next == ((void *)0)) + { + iter->end = 1; + return 0; + } + iter->start = ll_empty(iter->target); + iter->cursor = iter->cursor->next; + iter->index++; + return 1; +} +_Bool ll_iter_prev(struct linkedlist_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor->prev == ((void *)0)) + { + iter->start = 1; + return 0; + } + iter->end = ll_empty(iter->target); + iter->cursor = iter->cursor->prev; + iter->index--; + return 1; +} +_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor->next == ((void *)0)) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + iter->start = ll_empty(iter->target); + iter->index += steps; + for (size_t i = 0; i < steps; i++) + iter->cursor = iter->cursor->next; + return 1; +} +_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor->prev == ((void *)0)) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + iter->end = ll_empty(iter->target); + iter->index -= steps; + for (size_t i = 0; i < steps; i++) + iter->cursor = iter->cursor->prev; + return 1; +} +_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return ll_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return ll_iter_advance(iter, index - iter->index); + return 1; +} +size_t ll_iter_value(struct linkedlist_iter *iter) +{ + if (ll_empty(iter->target)) + return (size_t){ 0 }; + return iter->cursor->value; +} +size_t *ll_iter_rvalue(struct linkedlist_iter *iter) +{ + if (ll_empty(iter->target)) + return ((void *)0); + return &(iter->cursor->value); +} +size_t ll_iter_index(struct linkedlist_iter *iter) +{ + return iter->index; +} +struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter) +{ + return iter->cursor; +} struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) { struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node)); @@ -587,151 +734,38 @@ struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_) { return _node_->prev; } -struct linkedlist_iter ll_iter_start(struct linkedlist *target) +_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr) { - struct linkedlist_iter iter; - iter.target = target; - iter.cursor = target->head; - iter.index = 0; - iter.start = 1; - iter.end = ll_empty(target); - return iter; + struct linkedlist *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "count:%" + "I64u" + ", " + "head:%p, " + "tail:%p, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, + (l_)->callbacks); } -struct linkedlist_iter ll_iter_end(struct linkedlist *target) +_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) { - struct linkedlist_iter iter; - iter.target = target; - iter.cursor = target->tail; - iter.index = 0; - iter.start = ll_empty(target); - iter.end = 1; - if (!ll_empty(target)) - iter.index = target->count - 1; - return iter; -} -_Bool ll_iter_at_start(struct linkedlist_iter *iter) -{ - return ll_empty(iter->target) || iter->start; -} -_Bool ll_iter_at_end(struct linkedlist_iter *iter) -{ - return ll_empty(iter->target) || iter->end; -} -_Bool ll_iter_to_start(struct linkedlist_iter *iter) -{ - if (!ll_empty(iter->target)) + fprintf(fptr, "%s", start); + struct linkedlist_node *scan = _list_->head; + while (scan != ((void *)0)) { - iter->cursor = iter->target->head; - iter->index = 0; - iter->start = 1; - iter->end = ll_empty(iter->target); - return 1; + if (!_list_->f_val->str(fptr, scan->value)) + return 0; + scan = scan->next; + if (scan) + fprintf(fptr, "%s", separator); } - return 0; -} -_Bool ll_iter_to_end(struct linkedlist_iter *iter) -{ - if (!ll_empty(iter->target)) - { - iter->cursor = iter->target->tail; - iter->index = iter->target->count - 1; - iter->start = ll_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool ll_iter_next(struct linkedlist_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor->next == ((void *)0)) - { - iter->end = 1; - return 0; - } - iter->start = ll_empty(iter->target); - iter->cursor = iter->cursor->next; - iter->index++; + fprintf(fptr, "%s", end); return 1; } -_Bool ll_iter_prev(struct linkedlist_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor->prev == ((void *)0)) - { - iter->start = 1; - return 0; - } - iter->end = ll_empty(iter->target); - iter->cursor = iter->cursor->prev; - iter->index--; - return 1; -} -_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor->next == ((void *)0)) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - iter->start = ll_empty(iter->target); - iter->index += steps; - for (size_t i = 0; i < steps; i++) - iter->cursor = iter->cursor->next; - return 1; -} -_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor->prev == ((void *)0)) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - iter->end = ll_empty(iter->target); - iter->index -= steps; - for (size_t i = 0; i < steps; i++) - iter->cursor = iter->cursor->prev; - return 1; -} -_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return ll_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return ll_iter_advance(iter, index - iter->index); - return 1; -} -size_t ll_iter_value(struct linkedlist_iter *iter) -{ - if (ll_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->value; -} -size_t *ll_iter_rvalue(struct linkedlist_iter *iter) -{ - if (ll_empty(iter->target)) - return ((void *)0); - return &(iter->cursor->value); -} -size_t ll_iter_index(struct linkedlist_iter *iter) -{ - return iter->index; -} -struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter) -{ - return iter->cursor; -} #endif /* CMC_TEST_SRC_LINKEDLIST */ diff --git a/tests/main/src/list.c b/tests/main/src/list.c index eeca0cf..5c5ffbf 100644 --- a/tests/main/src/list.c +++ b/tests/main/src/list.c @@ -22,13 +22,6 @@ struct list_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct list_iter -{ - struct list *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct list *l_new(size_t capacity, struct list_fval *f_val); struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -41,11 +34,6 @@ _Bool l_push_back(struct list *_list_, size_t value); _Bool l_pop_front(struct list *_list_); _Bool l_pop_at(struct list *_list_, size_t index); _Bool l_pop_back(struct list *_list_); -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); size_t l_front(struct list *_list_); size_t l_get(struct list *_list_, size_t index); size_t *l_get_ref(struct list *_list_, size_t index); @@ -61,8 +49,13 @@ int l_flag(struct list *_list_); _Bool l_resize(struct list *_list_, size_t capacity); struct list *l_copy_of(struct list *_list_); _Bool l_equals(struct list *_list1_, struct list *_list2_); -struct cmc_string l_to_string(struct list *_list_); -_Bool l_print(struct list *_list_, FILE *fptr); +struct list_iter +{ + struct list *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct list_iter l_iter_start(struct list *target); struct list_iter l_iter_end(struct list *target); _Bool l_iter_at_start(struct list_iter *iter); @@ -77,31 +70,21 @@ _Bool l_iter_go_to(struct list_iter *iter, size_t index); size_t l_iter_value(struct list_iter *iter); size_t *l_iter_rvalue(struct list_iter *iter); size_t l_iter_index(struct list_iter *iter); +_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); +_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); +_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); +struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); +_Bool l_to_string(struct list *_list_, FILE *fptr); +_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end); struct list *l_new(size_t capacity, struct list_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - struct list *_list_ = alloc->malloc(sizeof(struct list)); - if (!_list_) - return ((void *)0); - _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_list_->buffer) - { - alloc->free(_list_); - return ((void *)0); - } - _list_->capacity = capacity; - _list_->count = 0; - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - _list_->callbacks = ((void *)0); - return _list_; + return l_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!f_val) @@ -122,7 +105,7 @@ struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_a _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; return _list_; } void l_clear(struct list *_list_) @@ -148,11 +131,12 @@ void l_free(struct list *_list_) } void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool l_push_front(struct list *_list_, size_t value) @@ -169,8 +153,9 @@ _Bool l_push_front(struct list *_list_, size_t value) _list_->buffer[0] = value; _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool l_push_at(struct list *_list_, size_t value, size_t index) @@ -189,8 +174,9 @@ _Bool l_push_at(struct list *_list_, size_t value, size_t index) _list_->buffer[index] = value; _list_->count++; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool l_push_back(struct list *_list_, size_t value) @@ -202,8 +188,9 @@ _Bool l_push_back(struct list *_list_, size_t value) } _list_->buffer[_list_->count++] = value; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool l_pop_front(struct list *_list_) @@ -216,8 +203,9 @@ _Bool l_pop_front(struct list *_list_) memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } _Bool l_pop_at(struct list *_list_, size_t index) @@ -235,8 +223,9 @@ _Bool l_pop_at(struct list *_list_, size_t index) memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } _Bool l_pop_back(struct list *_list_) @@ -245,128 +234,11 @@ _Bool l_pop_back(struct list *_list_) return 0; _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); - memcpy(_list_->buffer, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); - return 1; -} -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (index > _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (index == 0) - return l_seq_push_front(_list_, values, size); - else if (index == _list_->count) - return l_seq_push_back(_list_, values, size); - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); - memcpy(_list_->buffer + index, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); - return 1; -} -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); - return 1; -} -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) -{ - if (from > to) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (to >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - size_t length = (to - from + 1); - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); - _list_->count -= to - from + 1; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); - return 1; -} -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) -{ - if (from > to) - { - _list_->flag = CMC_FLAG_INVALID; - return ((void *)0); - } - if (to >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - size_t length = to - from + 1; - struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, _list_->callbacks); - if (!result) - { - _list_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); - _list_->count -= length; - result->count = length; - _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); - return result; -} size_t l_front(struct list *_list_) { if (l_empty(_list_)) @@ -375,8 +247,9 @@ size_t l_front(struct list *_list_) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[0]; } size_t l_get(struct list *_list_, size_t index) @@ -392,8 +265,9 @@ size_t l_get(struct list *_list_, size_t index) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[index]; } size_t *l_get_ref(struct list *_list_, size_t index) @@ -409,8 +283,9 @@ size_t *l_get_ref(struct list *_list_, size_t index) return ((void *)0); } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return &(_list_->buffer[index]); } size_t l_back(struct list *_list_) @@ -421,8 +296,9 @@ size_t l_back(struct list *_list_) return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[_list_->count - 1]; } size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) @@ -451,8 +327,9 @@ size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) } } } - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return result; } _Bool l_contains(struct list *_list_, size_t value) @@ -467,8 +344,9 @@ _Bool l_contains(struct list *_list_, size_t value) break; } } - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return result; } _Bool l_empty(struct list *_list_) @@ -513,18 +391,20 @@ _Bool l_resize(struct list *_list_, size_t capacity) } _list_->buffer = new_buffer; _list_->capacity = capacity; - if (_list_->callbacks && _list_->callbacks->resize) - _list_->callbacks->resize(); + if ((_list_)->callbacks && (_list_)->callbacks->resize) + (_list_)->callbacks->resize(); + ; return 1; } struct list *l_copy_of(struct list *_list_) { - struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, _list_->callbacks); + struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); if (!result) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } + (result)->callbacks = _list_->callbacks; if (_list_->f_val->cpy) { for (size_t i = 0; i < _list_->count; i++) @@ -544,7 +424,7 @@ _Bool l_equals(struct list *_list1_, struct list *_list2_) return 0; for (size_t i = 0; i < _list1_->count; i++) { - if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) + if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) return 0; } return 1; @@ -681,5 +561,161 @@ size_t l_iter_index(struct list_iter *iter) { return iter->cursor; } +_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); + memcpy(_list_->buffer, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (index > _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + if (index == 0) + return l_seq_push_front(_list_, values, size); + else if (index == _list_->count) + return l_seq_push_back(_list_, values, size); + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); + memcpy(_list_->buffer + index, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) +{ + if (from > to) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (to >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + size_t length = (to - from + 1); + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); + _list_->count -= to - from + 1; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) +{ + if (from > to) + { + _list_->flag = CMC_FLAG_INVALID; + return ((void *)0); + } + if (to >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return ((void *)0); + } + size_t length = to - from + 1; + struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks); + if (!result) + { + _list_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); + _list_->count -= length; + result->count = length; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return result; +} +_Bool l_to_string(struct list *_list_, FILE *fptr) +{ + struct list *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, + (l_)->callbacks); +} +_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _list_->count; i++) + { + if (!_list_->f_val->str(fptr, _list_->buffer[i])) + return 0; + if (i + 1 < _list_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_LIST */ diff --git a/tests/main/src/queue.c b/tests/main/src/queue.c index b0a4f7d..e5e6d85 100644 --- a/tests/main/src/queue.c +++ b/tests/main/src/queue.c @@ -50,8 +50,6 @@ int q_flag(struct queue *_queue_); _Bool q_resize(struct queue *_queue_, size_t capacity); struct queue *q_copy_of(struct queue *_queue_); _Bool q_equals(struct queue *_queue1_, struct queue *_queue2_); -struct cmc_string q_to_string(struct queue *_queue_); -_Bool q_print(struct queue *_queue_, FILE *fptr); struct queue_iter q_iter_start(struct queue *target); struct queue_iter q_iter_end(struct queue *target); _Bool q_iter_at_start(struct queue_iter *iter); @@ -66,35 +64,16 @@ _Bool q_iter_go_to(struct queue_iter *iter, size_t index); size_t q_iter_value(struct queue_iter *iter); size_t *q_iter_rvalue(struct queue_iter *iter); size_t q_iter_index(struct queue_iter *iter); +_Bool q_to_string(struct queue *_queue_, FILE *fptr); +_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end); struct queue *q_new(size_t capacity, struct queue_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct queue *_queue_ = alloc->malloc(sizeof(struct queue)); - if (!_queue_) - return ((void *)0); - _queue_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_queue_->buffer) - { - alloc->free(_queue_); - return ((void *)0); - } - _queue_->capacity = capacity; - _queue_->count = 0; - _queue_->front = 0; - _queue_->back = 0; - _queue_->flag = CMC_FLAG_OK; - _queue_->f_val = f_val; - _queue_->alloc = alloc; - _queue_->callbacks = ((void *)0); - return _queue_; + return q_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!f_val) @@ -117,7 +96,7 @@ struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc _queue_->flag = CMC_FLAG_OK; _queue_->f_val = f_val; _queue_->alloc = alloc; - _queue_->callbacks = callbacks; + (_queue_)->callbacks = callbacks; return _queue_; } void q_clear(struct queue *_queue_) @@ -151,11 +130,12 @@ void q_free(struct queue *_queue_) } void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _queue_->alloc = &cmc_alloc_node_default; else _queue_->alloc = alloc; - _queue_->callbacks = callbacks; + (_queue_)->callbacks = callbacks; _queue_->flag = CMC_FLAG_OK; } _Bool q_enqueue(struct queue *_queue_, size_t value) @@ -169,8 +149,9 @@ _Bool q_enqueue(struct queue *_queue_, size_t value) _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; _queue_->count++; _queue_->flag = CMC_FLAG_OK; - if (_queue_->callbacks && _queue_->callbacks->create) - _queue_->callbacks->create(); + if ((_queue_)->callbacks && (_queue_)->callbacks->create) + (_queue_)->callbacks->create(); + ; return 1; } _Bool q_dequeue(struct queue *_queue_) @@ -184,8 +165,9 @@ _Bool q_dequeue(struct queue *_queue_) _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; _queue_->count--; _queue_->flag = CMC_FLAG_OK; - if (_queue_->callbacks && _queue_->callbacks->delete) - _queue_->callbacks->delete (); + if ((_queue_)->callbacks && (_queue_)->callbacks->delete) + (_queue_)->callbacks->delete (); + ; return 1; } size_t q_peek(struct queue *_queue_) @@ -196,8 +178,9 @@ size_t q_peek(struct queue *_queue_) return (size_t){ 0 }; } _queue_->flag = CMC_FLAG_OK; - if (_queue_->callbacks && _queue_->callbacks->read) - _queue_->callbacks->read(); + if ((_queue_)->callbacks && (_queue_)->callbacks->read) + (_queue_)->callbacks->read(); + ; return _queue_->buffer[_queue_->front]; } _Bool q_contains(struct queue *_queue_, size_t value) @@ -213,8 +196,9 @@ _Bool q_contains(struct queue *_queue_, size_t value) } i = (i + 1) % _queue_->capacity; } - if (_queue_->callbacks && _queue_->callbacks->read) - _queue_->callbacks->read(); + if ((_queue_)->callbacks && (_queue_)->callbacks->read) + (_queue_)->callbacks->read(); + ; return result; } _Bool q_empty(struct queue *_queue_) @@ -264,18 +248,20 @@ _Bool q_resize(struct queue *_queue_, size_t capacity) _queue_->back = _queue_->count; success: _queue_->flag = CMC_FLAG_OK; - if (_queue_->callbacks && _queue_->callbacks->resize) - _queue_->callbacks->resize(); + if ((_queue_)->callbacks && (_queue_)->callbacks->resize) + (_queue_)->callbacks->resize(); + ; return 1; } struct queue *q_copy_of(struct queue *_queue_) { - struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, _queue_->callbacks); + struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0)); if (!result) { _queue_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _queue_->callbacks; if (_queue_->f_val->cpy) { for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) @@ -468,5 +454,45 @@ size_t q_iter_index(struct queue_iter *iter) { return iter->index; } +_Bool q_to_string(struct queue *_queue_, FILE *fptr) +{ + struct queue *q_ = _queue_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "front:%" + "I64u" + ", " + "back:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag, + q_->f_val, q_->alloc, (q_)->callbacks); +} +_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) + { + if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) + return 0; + i = (i + 1) % _queue_->capacity; + if (j + 1 < _queue_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_QUEUE */ diff --git a/tests/main/src/sortedlist.c b/tests/main/src/sortedlist.c index cb2f97f..480a08c 100644 --- a/tests/main/src/sortedlist.c +++ b/tests/main/src/sortedlist.c @@ -23,13 +23,6 @@ struct sortedlist_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct sortedlist_iter -{ - struct sortedlist *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val); struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -52,8 +45,13 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity); void sl_sort(struct sortedlist *_list_); struct sortedlist *sl_copy_of(struct sortedlist *_list_); _Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_); -struct cmc_string sl_to_string(struct sortedlist *_list_); -_Bool sl_print(struct sortedlist *_list_, FILE *fptr); +struct sortedlist_iter +{ + struct sortedlist *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct sortedlist_iter sl_iter_start(struct sortedlist *target); struct sortedlist_iter sl_iter_end(struct sortedlist *target); _Bool sl_iter_at_start(struct sortedlist_iter *iter); @@ -67,38 +65,20 @@ _Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps); _Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index); size_t sl_iter_value(struct sortedlist_iter *iter); size_t sl_iter_index(struct sortedlist_iter *iter); +_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr); +_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value); static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value); void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist)); - if (!_list_) - return ((void *)0); - _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_list_->buffer) - { - alloc->free(_list_); - return ((void *)0); - } - _list_->capacity = capacity; - _list_->count = 0; - _list_->is_sorted = 0; - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - _list_->callbacks = ((void *)0); - return _list_; + return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!alloc) @@ -118,7 +98,7 @@ struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; return _list_; } void sl_clear(struct sortedlist *_list_) @@ -144,11 +124,12 @@ void sl_free(struct sortedlist *_list_) } void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; - _list_->callbacks = callbacks; + (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool sl_insert(struct sortedlist *_list_, size_t value) @@ -161,8 +142,9 @@ _Bool sl_insert(struct sortedlist *_list_, size_t value) _list_->buffer[_list_->count++] = value; _list_->is_sorted = 0; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->create) - _list_->callbacks->create(); + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; return 1; } _Bool sl_remove(struct sortedlist *_list_, size_t index) @@ -180,8 +162,9 @@ _Bool sl_remove(struct sortedlist *_list_, size_t index) memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->delete) - _list_->callbacks->delete (); + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; return 1; } size_t sl_max(struct sortedlist *_list_) @@ -193,8 +176,9 @@ size_t sl_max(struct sortedlist *_list_) } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[_list_->count - 1]; } size_t sl_min(struct sortedlist *_list_) @@ -206,8 +190,9 @@ size_t sl_min(struct sortedlist *_list_) } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[0]; } size_t sl_get(struct sortedlist *_list_, size_t index) @@ -224,16 +209,18 @@ size_t sl_get(struct sortedlist *_list_, size_t index) } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return _list_->buffer[index]; } size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start) { _list_->flag = CMC_FLAG_OK; sl_sort(_list_); - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; if (from_start) { return sl_impl_binary_search_first(_list_, value); @@ -246,8 +233,9 @@ _Bool sl_contains(struct sortedlist *_list_, size_t value) if (sl_empty(_list_)) return 0; sl_sort(_list_); - if (_list_->callbacks && _list_->callbacks->read) - _list_->callbacks->read(); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; return sl_impl_binary_search_first(_list_, value) < _list_->count; } _Bool sl_empty(struct sortedlist *_list_) @@ -289,8 +277,9 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity) _list_->capacity = capacity; success: _list_->flag = CMC_FLAG_OK; - if (_list_->callbacks && _list_->callbacks->resize) - _list_->callbacks->resize(); + if ((_list_)->callbacks && (_list_)->callbacks->resize) + (_list_)->callbacks->resize(); + ; return 1; } void sl_sort(struct sortedlist *_list_) @@ -304,12 +293,13 @@ void sl_sort(struct sortedlist *_list_) } struct sortedlist *sl_copy_of(struct sortedlist *_list_) { - struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, _list_->callbacks); + struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); if (!result) { _list_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _list_->callbacks; if (_list_->f_val->cpy) { for (size_t i = 0; i < _list_->count; i++) @@ -334,6 +324,95 @@ _Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_) } return 1; } +static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value) +{ + if (sl_empty(_list_)) + return 1; + size_t L = 0; + size_t R = _list_->count; + while (L < R) + { + size_t M = L + (R - L) / 2; + if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) + L = M + 1; + else + R = M; + } + if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) + return L; + return _list_->count; +} +static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value) +{ + if (sl_empty(_list_)) + return 1; + size_t L = 0; + size_t R = _list_->count; + while (L < R) + { + size_t M = L + (R - L) / 2; + if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) + R = M; + else + L = M + 1; + } + if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) + return L - 1; + return _list_->count; +} +void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) +{ + while (low < high) + { + if (high - low < 10) + { + sl_impl_sort_insertion(array, cmp, low, high); + break; + } + else + { + size_t pivot = array[high]; + size_t pindex = low; + for (size_t i = low; i < high; i++) + { + if (cmp(array[i], pivot) <= 0) + { + size_t _tmp_ = array[i]; + array[i] = array[pindex]; + array[pindex] = _tmp_; + pindex++; + } + } + size_t _tmp_ = array[pindex]; + array[pindex] = array[high]; + array[high] = _tmp_; + if (pindex - low < high - pindex) + { + sl_impl_sort_quicksort(array, cmp, low, pindex - 1); + low = pindex + 1; + } + else + { + sl_impl_sort_quicksort(array, cmp, pindex + 1, high); + high = pindex - 1; + } + } + } +} +void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) +{ + for (size_t i = low + 1; i <= high; i++) + { + size_t _tmp_ = array[i]; + size_t j = i; + while (j > low && cmp(array[j - 1], _tmp_) > 0) + { + array[j] = array[j - 1]; + j--; + } + array[j] = _tmp_; + } +} struct sortedlist_iter sl_iter_start(struct sortedlist *target) { sl_sort(target); @@ -462,94 +541,40 @@ size_t sl_iter_index(struct sortedlist_iter *iter) { return iter->cursor; } -static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value) +_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr) { - if (sl_empty(_list_)) - return 1; - size_t L = 0; - size_t R = _list_->count; - while (L < R) - { - size_t M = L + (R - L) / 2; - if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) - L = M + 1; - else - R = M; - } - if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) - return L; - return _list_->count; + struct sortedlist *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "is_sorted:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count, + l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); } -static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value) +_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) { - if (sl_empty(_list_)) - return 1; - size_t L = 0; - size_t R = _list_->count; - while (L < R) + sl_sort(_list_); + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _list_->count; i++) { - size_t M = L + (R - L) / 2; - if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) - R = M; - else - L = M + 1; - } - if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) - return L - 1; - return _list_->count; -} -void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) -{ - while (low < high) - { - if (high - low < 10) - { - sl_impl_sort_insertion(array, cmp, low, high); - break; - } - else - { - size_t pivot = array[high]; - size_t pindex = low; - for (size_t i = low; i < high; i++) - { - if (cmp(array[i], pivot) <= 0) - { - size_t _tmp_ = array[i]; - array[i] = array[pindex]; - array[pindex] = _tmp_; - pindex++; - } - } - size_t _tmp_ = array[pindex]; - array[pindex] = array[high]; - array[high] = _tmp_; - if (pindex - low < high - pindex) - { - sl_impl_sort_quicksort(array, cmp, low, pindex - 1); - low = pindex + 1; - } - else - { - sl_impl_sort_quicksort(array, cmp, pindex + 1, high); - high = pindex - 1; - } - } - } -} -void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) -{ - for (size_t i = low + 1; i <= high; i++) - { - size_t _tmp_ = array[i]; - size_t j = i; - while (j > low && cmp(array[j - 1], _tmp_) > 0) - { - array[j] = array[j - 1]; - j--; - } - array[j] = _tmp_; + if (!_list_->f_val->str(fptr, _list_->buffer[i])) + return 0; + if (i + 1 < _list_->count) + fprintf(fptr, "%s", separator); } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_SORTEDLIST */ diff --git a/tests/main/src/stack.c b/tests/main/src/stack.c index 69ab69f..1be2b1a 100644 --- a/tests/main/src/stack.c +++ b/tests/main/src/stack.c @@ -22,13 +22,6 @@ struct stack_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct stack_iter -{ - struct stack *target; - size_t cursor; - _Bool start; - _Bool end; -}; struct stack *s_new(size_t capacity, struct stack_fval *f_val); struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -47,8 +40,13 @@ int s_flag(struct stack *_stack_); _Bool s_resize(struct stack *_stack_, size_t capacity); struct stack *s_copy_of(struct stack *_stack_); _Bool s_equals(struct stack *_stack1_, struct stack *_stack2_); -struct cmc_string s_to_string(struct stack *_stack_); -_Bool s_print(struct stack *_stack_, FILE *fptr); +struct stack_iter +{ + struct stack *target; + size_t cursor; + _Bool start; + _Bool end; +}; struct stack_iter s_iter_start(struct stack *target); struct stack_iter s_iter_end(struct stack *target); _Bool s_iter_at_start(struct stack_iter *iter); @@ -63,33 +61,16 @@ _Bool s_iter_go_to(struct stack_iter *iter, size_t index); size_t s_iter_value(struct stack_iter *iter); size_t *s_iter_rvalue(struct stack_iter *iter); size_t s_iter_index(struct stack_iter *iter); +_Bool s_to_string(struct stack *_stack_, FILE *fptr); +_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end); struct stack *s_new(size_t capacity, struct stack_fval *f_val) { - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - struct stack *_stack_ = alloc->malloc(sizeof(struct stack)); - if (!_stack_) - return ((void *)0); - _stack_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_stack_->buffer) - { - alloc->free(_stack_); - return ((void *)0); - } - _stack_->capacity = capacity; - _stack_->count = 0; - _stack_->flag = CMC_FLAG_OK; - _stack_->f_val = f_val; - _stack_->alloc = alloc; - _stack_->callbacks = ((void *)0); - return _stack_; + return s_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (capacity < 1) return ((void *)0); if (!f_val) @@ -110,7 +91,7 @@ struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc _stack_->flag = CMC_FLAG_OK; _stack_->f_val = f_val; _stack_->alloc = alloc; - _stack_->callbacks = callbacks; + (_stack_)->callbacks = callbacks; return _stack_; } void s_clear(struct stack *_stack_) @@ -136,11 +117,12 @@ void s_free(struct stack *_stack_) } void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _stack_->alloc = &cmc_alloc_node_default; else _stack_->alloc = alloc; - _stack_->callbacks = callbacks; + (_stack_)->callbacks = callbacks; _stack_->flag = CMC_FLAG_OK; } _Bool s_push(struct stack *_stack_, size_t value) @@ -152,8 +134,9 @@ _Bool s_push(struct stack *_stack_, size_t value) } _stack_->buffer[_stack_->count++] = value; _stack_->flag = CMC_FLAG_OK; - if (_stack_->callbacks && _stack_->callbacks->create) - _stack_->callbacks->create(); + if ((_stack_)->callbacks && (_stack_)->callbacks->create) + (_stack_)->callbacks->create(); + ; return 1; } _Bool s_pop(struct stack *_stack_) @@ -165,8 +148,9 @@ _Bool s_pop(struct stack *_stack_) } _stack_->buffer[--_stack_->count] = (size_t){ 0 }; _stack_->flag = CMC_FLAG_OK; - if (_stack_->callbacks && _stack_->callbacks->delete) - _stack_->callbacks->delete (); + if ((_stack_)->callbacks && (_stack_)->callbacks->delete) + (_stack_)->callbacks->delete (); + ; return 1; } size_t s_top(struct stack *_stack_) @@ -177,8 +161,9 @@ size_t s_top(struct stack *_stack_) return (size_t){ 0 }; } _stack_->flag = CMC_FLAG_OK; - if (_stack_->callbacks && _stack_->callbacks->read) - _stack_->callbacks->read(); + if ((_stack_)->callbacks && (_stack_)->callbacks->read) + (_stack_)->callbacks->read(); + ; return _stack_->buffer[_stack_->count - 1]; } _Bool s_contains(struct stack *_stack_, size_t value) @@ -193,8 +178,9 @@ _Bool s_contains(struct stack *_stack_, size_t value) break; } } - if (_stack_->callbacks && _stack_->callbacks->read) - _stack_->callbacks->read(); + if ((_stack_)->callbacks && (_stack_)->callbacks->read) + (_stack_)->callbacks->read(); + ; return result; } _Bool s_empty(struct stack *_stack_) @@ -236,18 +222,20 @@ _Bool s_resize(struct stack *_stack_, size_t capacity) _stack_->capacity = capacity; success: _stack_->flag = CMC_FLAG_OK; - if (_stack_->callbacks && _stack_->callbacks->resize) - _stack_->callbacks->resize(); + if ((_stack_)->callbacks && (_stack_)->callbacks->resize) + (_stack_)->callbacks->resize(); + ; return 1; } struct stack *s_copy_of(struct stack *_stack_) { - struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, _stack_->callbacks); + struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0)); if (!result) { _stack_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (_stack_)->callbacks = callbacks; if (_stack_->f_val->cpy) { for (size_t i = 0; i < _stack_->count; i++) @@ -406,5 +394,38 @@ size_t s_iter_index(struct stack_iter *iter) return 0; return iter->target->count - 1 - iter->cursor; } +_Bool s_to_string(struct stack *_stack_, FILE *fptr) +{ + struct stack *s_ = _stack_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, + (s_)->callbacks); +} +_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _stack_->count; i > 0; i--) + { + if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) + return 0; + if (i - 1 != 0) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_STACK */ diff --git a/tests/main/src/treemap.c b/tests/main/src/treemap.c index 2f16e80..fa081be 100644 --- a/tests/main/src/treemap.c +++ b/tests/main/src/treemap.c @@ -40,16 +40,6 @@ struct treemap_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct treemap_iter -{ - struct treemap *target; - struct treemap_node *cursor; - struct treemap_node *first; - struct treemap_node *last; - size_t index; - _Bool start; - _Bool end; -}; struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val); struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -69,8 +59,16 @@ size_t tm_count(struct treemap *_map_); int tm_flag(struct treemap *_map_); struct treemap *tm_copy_of(struct treemap *_map_); _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_); -struct cmc_string tm_to_string(struct treemap *_map_); -_Bool tm_print(struct treemap *_map_, FILE *fptr); +struct treemap_iter +{ + struct treemap *target; + struct treemap_node *cursor; + struct treemap_node *first; + struct treemap_node *last; + size_t index; + _Bool start; + _Bool end; +}; struct treemap_iter tm_iter_start(struct treemap *target); struct treemap_iter tm_iter_end(struct treemap *target); _Bool tm_iter_at_start(struct treemap_iter *iter); @@ -86,6 +84,9 @@ size_t tm_iter_key(struct treemap_iter *iter); size_t tm_iter_value(struct treemap_iter *iter); size_t *tm_iter_rvalue(struct treemap_iter *iter); size_t tm_iter_index(struct treemap_iter *iter); +_Bool tm_to_string(struct treemap *_map_, FILE *fptr); +_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value); static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key); static unsigned char tm_impl_h(struct treemap_node *node); @@ -95,24 +96,12 @@ static void tm_impl_rotate_left(struct treemap_node **Z); static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node); struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val) { - if (!f_key || !f_val) - return ((void *)0); - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - struct treemap *_map_ = alloc->malloc(sizeof(struct treemap)); - if (!_map_) - return ((void *)0); - _map_->count = 0; - _map_->root = ((void *)0); - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - _map_->callbacks = ((void *)0); - return _map_; + return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0)); } struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!f_key || !f_val) return ((void *)0); if (!alloc) @@ -126,7 +115,7 @@ struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; return _map_; } void tm_clear(struct treemap *_map_) @@ -193,11 +182,12 @@ void tm_free(struct treemap *_map_) } void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; - _map_->callbacks = callbacks; + (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) @@ -255,8 +245,9 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value) } _map_->count++; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->create) - _map_->callbacks->create(); + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; return 1; } _Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value) @@ -271,8 +262,9 @@ _Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old *old_value = node->value; node->value = new_value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->update) - _map_->callbacks->update(); + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; return 1; } _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) @@ -383,8 +375,9 @@ _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) _map_->root = ((void *)0); _map_->count--; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->delete) - _map_->callbacks->delete (); + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; return 1; } _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) @@ -402,8 +395,9 @@ _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) if (value) *value = scan->value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) @@ -421,8 +415,9 @@ _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) if (value) *value = scan->value; _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return 1; } size_t tm_get(struct treemap *_map_, size_t key) @@ -439,8 +434,9 @@ size_t tm_get(struct treemap *_map_, size_t key) return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return node->value; } size_t *tm_get_ref(struct treemap *_map_, size_t key) @@ -457,15 +453,17 @@ size_t *tm_get_ref(struct treemap *_map_, size_t key) return ((void *)0); } _map_->flag = CMC_FLAG_OK; - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return &(node->value); } _Bool tm_contains(struct treemap *_map_, size_t key) { _Bool result = tm_impl_get_node(_map_, key) != ((void *)0); - if (_map_->callbacks && _map_->callbacks->read) - _map_->callbacks->read(); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; return result; } _Bool tm_empty(struct treemap *_map_) @@ -499,7 +497,7 @@ struct treemap *tm_copy_of(struct treemap *_map_) value = _map_->f_val->cpy(value); tm_insert(result, key, value); } - result->callbacks = _map_->callbacks; + (result)->callbacks = _map_->callbacks; _map_->flag = CMC_FLAG_OK; return result; } @@ -520,6 +518,122 @@ _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) } return 1; } +static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value) +{ + struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); + if (!node) + return ((void *)0); + node->key = key; + node->value = value; + node->right = ((void *)0); + node->left = ((void *)0); + node->parent = ((void *)0); + node->height = 0; + return node; +} +static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key) +{ + struct treemap_node *scan = _map_->root; + while (scan != ((void *)0)) + { + if (_map_->f_key->cmp(scan->key, key) > 0) + scan = scan->left; + else if (_map_->f_key->cmp(scan->key, key) < 0) + scan = scan->right; + else + return scan; + } + return ((void *)0); +} +static unsigned char tm_impl_h(struct treemap_node *node) +{ + if (node == ((void *)0)) + return 0; + return node->height; +} +static unsigned char tm_impl_hupdate(struct treemap_node *node) +{ + if (node == ((void *)0)) + return 0; + unsigned char h_l = tm_impl_h(node->left); + unsigned char h_r = tm_impl_h(node->right); + return 1 + (h_l > h_r ? h_l : h_r); +} +static void tm_impl_rotate_right(struct treemap_node **Z) +{ + struct treemap_node *root = *Z; + struct treemap_node *new_root = root->left; + if (root->parent != ((void *)0)) + { + if (root->parent->left == root) + root->parent->left = new_root; + else + root->parent->right = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->left = new_root->right; + if (root->left) + root->left->parent = root; + new_root->right = root; + root->height = tm_impl_hupdate(root); + new_root->height = tm_impl_hupdate(new_root); + *Z = new_root; +} +static void tm_impl_rotate_left(struct treemap_node **Z) +{ + struct treemap_node *root = *Z; + struct treemap_node *new_root = root->right; + if (root->parent != ((void *)0)) + { + if (root->parent->right == root) + root->parent->right = new_root; + else + root->parent->left = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->right = new_root->left; + if (root->right) + root->right->parent = root; + new_root->left = root; + root->height = tm_impl_hupdate(root); + new_root->height = tm_impl_hupdate(new_root); + *Z = new_root; +} +static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node) +{ + struct treemap_node *scan = node, *child = ((void *)0); + int balance; + _Bool is_root = 0; + while (scan != ((void *)0)) + { + if (scan->parent == ((void *)0)) + is_root = 1; + scan->height = tm_impl_hupdate(scan); + balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); + if (balance >= 2) + { + child = scan->right; + if (tm_impl_h(child->right) < tm_impl_h(child->left)) + tm_impl_rotate_right(&(scan->right)); + tm_impl_rotate_left(&scan); + } + else if (balance <= -2) + { + child = scan->left; + if (tm_impl_h(child->left) < tm_impl_h(child->right)) + tm_impl_rotate_left(&(scan->left)); + tm_impl_rotate_right(&scan); + } + if (is_root) + { + _map_->root = scan; + is_root = 0; + } + scan = scan->parent; + } +} struct treemap_iter tm_iter_start(struct treemap *target) { struct treemap_iter iter; @@ -715,121 +829,64 @@ size_t tm_iter_index(struct treemap_iter *iter) { return iter->index; } -static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value) +_Bool tm_to_string(struct treemap *_map_, FILE *fptr) { - struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); - if (!node) - return ((void *)0); - node->key = key; - node->value = value; - node->right = ((void *)0); - node->left = ((void *)0); - node->parent = ((void *)0); - node->height = 0; - return node; + struct treemap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "root:%p, " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "f_key:%p, " + "alloc:%p, " + "callbacks:%p }", + "treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, + m_->alloc, (m_)->callbacks); } -static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key) +_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) { - struct treemap_node *scan = _map_->root; - while (scan != ((void *)0)) + fprintf(fptr, "%s", start); + struct treemap_node *root = _map_->root; + _Bool left_done = 0; + size_t i = 0; + while (root) { - if (_map_->f_key->cmp(scan->key, key) > 0) - scan = scan->left; - else if (_map_->f_key->cmp(scan->key, key) < 0) - scan = scan->right; - else - return scan; - } - return ((void *)0); -} -static unsigned char tm_impl_h(struct treemap_node *node) -{ - if (node == ((void *)0)) - return 0; - return node->height; -} -static unsigned char tm_impl_hupdate(struct treemap_node *node) -{ - if (node == ((void *)0)) - return 0; - unsigned char h_l = tm_impl_h(node->left); - unsigned char h_r = tm_impl_h(node->right); - return 1 + (h_l > h_r ? h_l : h_r); -} -static void tm_impl_rotate_right(struct treemap_node **Z) -{ - struct treemap_node *root = *Z; - struct treemap_node *new_root = root->left; - if (root->parent != ((void *)0)) - { - if (root->parent->left == root) - root->parent->left = new_root; - else - root->parent->right = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->left = new_root->right; - if (root->left) - root->left->parent = root; - new_root->right = root; - root->height = tm_impl_hupdate(root); - new_root->height = tm_impl_hupdate(new_root); - *Z = new_root; -} -static void tm_impl_rotate_left(struct treemap_node **Z) -{ - struct treemap_node *root = *Z; - struct treemap_node *new_root = root->right; - if (root->parent != ((void *)0)) - { - if (root->parent->right == root) - root->parent->right = new_root; - else - root->parent->left = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->right = new_root->left; - if (root->right) - root->right->parent = root; - new_root->left = root; - root->height = tm_impl_hupdate(root); - new_root->height = tm_impl_hupdate(new_root); - *Z = new_root; -} -static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node) -{ - struct treemap_node *scan = node, *child = ((void *)0); - int balance; - _Bool is_root = 0; - while (scan != ((void *)0)) - { - if (scan->parent == ((void *)0)) - is_root = 1; - scan->height = tm_impl_hupdate(scan); - balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); - if (balance >= 2) + if (!left_done) { - child = scan->right; - if (tm_impl_h(child->right) < tm_impl_h(child->left)) - tm_impl_rotate_right(&(scan->right)); - tm_impl_rotate_left(&scan); + while (root->left) + root = root->left; } - else if (balance <= -2) + if (!_map_->f_key->str(fptr, root->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, root->value)) + return 0; + if (++i < _map_->count) + fprintf(fptr, "%s", separator); + left_done = 1; + if (root->right) { - child = scan->left; - if (tm_impl_h(child->left) < tm_impl_h(child->right)) - tm_impl_rotate_left(&(scan->left)); - tm_impl_rotate_right(&scan); + left_done = 0; + root = root->right; } - if (is_root) + else if (root->parent) { - _map_->root = scan; - is_root = 0; + while (root->parent && root == root->parent->right) + root = root->parent; + if (!root->parent) + break; + root = root->parent; } - scan = scan->parent; + else + break; } + fprintf(fptr, "%s", end); + return 1; } #endif /* CMC_TEST_SRC_TREEMAP */ diff --git a/tests/main/src/treeset.c b/tests/main/src/treeset.c index a1969ef..1bf5884 100644 --- a/tests/main/src/treeset.c +++ b/tests/main/src/treeset.c @@ -55,8 +55,6 @@ size_t ts_count(struct treeset *_set_); int ts_flag(struct treeset *_set_); struct treeset *ts_copy_of(struct treeset *_set_); _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); -struct cmc_string ts_to_string(struct treeset *_set_); -_Bool ts_print(struct treeset *_set_, FILE *fptr); struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); @@ -79,12 +77,8 @@ _Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); _Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); size_t ts_iter_value(struct treeset_iter *iter); size_t ts_iter_index(struct treeset_iter *iter); -static inline size_t ts_impl_default_value(void) -{ - size_t _empty_value_; - memset(&_empty_value_, 0, sizeof(size_t)); - return _empty_value_; -} +_Bool ts_to_string(struct treeset *_set_, FILE *fptr); +_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value); static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value); static unsigned char ts_impl_h(struct treeset_node *node); @@ -94,22 +88,11 @@ static void ts_impl_rotate_left(struct treeset_node **Z); static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node); struct treeset *ts_new(struct treeset_fval *f_val) { - if (!f_val) - return ((void *)0); - struct cmc_alloc_node *alloc = &cmc_alloc_node_default; - struct treeset *_set_ = alloc->malloc(sizeof(struct treeset)); - if (!_set_) - return ((void *)0); - _set_->count = 0; - _set_->root = ((void *)0); - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - _set_->callbacks = ((void *)0); - return _set_; + return ts_new_custom(f_val, ((void *)0), ((void *)0)); } struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!f_val) return ((void *)0); if (!alloc) @@ -122,7 +105,7 @@ struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; return _set_; } void ts_clear(struct treeset *_set_) @@ -185,11 +168,12 @@ void ts_free(struct treeset *_set_) } void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; - _set_->callbacks = callbacks; + (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool ts_insert(struct treeset *_set_, size_t value) @@ -247,8 +231,9 @@ _Bool ts_insert(struct treeset *_set_, size_t value) } _set_->count++; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->create) - _set_->callbacks->create(); + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; return 1; } _Bool ts_remove(struct treeset *_set_, size_t value) @@ -355,8 +340,9 @@ _Bool ts_remove(struct treeset *_set_, size_t value) _set_->root = ((void *)0); _set_->count--; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->delete) - _set_->callbacks->delete (); + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; return 1; } _Bool ts_max(struct treeset *_set_, size_t *value) @@ -372,8 +358,9 @@ _Bool ts_max(struct treeset *_set_, size_t *value) if (value) *value = scan->value; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool ts_min(struct treeset *_set_, size_t *value) @@ -389,15 +376,17 @@ _Bool ts_min(struct treeset *_set_, size_t *value) if (value) *value = scan->value; _set_->flag = CMC_FLAG_OK; - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return 1; } _Bool ts_contains(struct treeset *_set_, size_t value) { _Bool result = ts_impl_get_node(_set_, value) != ((void *)0); - if (_set_->callbacks && _set_->callbacks->read) - _set_->callbacks->read(); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; return result; } _Bool ts_empty(struct treeset *_set_) @@ -414,12 +403,13 @@ int ts_flag(struct treeset *_set_) } struct treeset *ts_copy_of(struct treeset *_set_) { - struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks); + struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } + (result)->callbacks = _set_->callbacks; if (!ts_empty(_set_)) { struct treeset_iter iter = ts_iter_start(_set_); @@ -450,7 +440,7 @@ _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) } struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); @@ -463,11 +453,12 @@ struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) { ts_insert(_set_r_, ts_iter_value(&iter2)); } + (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; @@ -479,11 +470,12 @@ struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) if (ts_impl_get_node(_set_B_, value) != ((void *)0)) ts_insert(_set_r_, value); } + (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter = ts_iter_start(_set1_); @@ -493,11 +485,12 @@ struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) if (ts_impl_get_node(_set2_, value) == ((void *)0)) ts_insert(_set_r_, value); } + (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); @@ -514,6 +507,7 @@ struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset * if (ts_impl_get_node(_set1_, value) == ((void *)0)) ts_insert(_set_r_, value); } + (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } _Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) @@ -870,5 +864,58 @@ static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) scan = scan->parent; } } +_Bool ts_to_string(struct treeset *_set_, FILE *fptr) +{ + struct treeset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "root:%p, " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); +} +_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + struct treeset_node *root = _set_->root; + _Bool left_done = 0; + size_t i = 0; + while (root) + { + if (!left_done) + { + while (root->left) + root = root->left; + } + if (!_set_->f_val->str(fptr, root->value)) + return 0; + if (++i < _set_->count) + fprintf(fptr, "%s", separator); + left_done = 1; + if (root->right) + { + left_done = 0; + root = root->right; + } + else if (root->parent) + { + while (root->parent && root == root->parent->right) + root = root->parent; + if (!root->parent) + break; + root = root->parent; + } + else + break; + } + fprintf(fptr, "%s", end); + return 1; +} #endif /* CMC_TEST_SRC_TREESET */ diff --git a/tests/main/unt/bitset.c b/tests/main/unt/bitset.c index 2524a4e..3e6053f 100644 --- a/tests/main/unt/bitset.c +++ b/tests/main/unt/bitset.c @@ -8,7 +8,6 @@ struct cmc_alloc_node *bs_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; CMC_CREATE_UNIT(BitSet, true, { - const size_t word_bytes = sizeof(cmc_bitset_word); const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; printf("%s", cmc_test_color(5)); @@ -421,8 +420,8 @@ CMC_CREATE_UNIT(BitSet, true, { }); CMC_CREATE_UNIT(BitSetIter, true, { - const size_t word_bytes = sizeof(cmc_bitset_word); - const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; + // const size_t word_bytes = sizeof(cmc_bitset_word); + // const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; printf("%s", cmc_test_color(5)); printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n"); diff --git a/tests/main/unt/hashbidimap.c b/tests/main/unt/hashbidimap.c index 3d73272..1d8bd1e 100644 --- a/tests/main/unt/hashbidimap.c +++ b/tests/main/unt/hashbidimap.c @@ -793,10 +793,13 @@ CMC_CREATE_UNIT(HashBidiMap, true, { }); }); -CMC_CREATE_UNIT(HashBidiMapIter, true, - { - - }); +CMC_CREATE_UNIT(HashBidiMapIter, true, { + CMC_CREATE_TEST(PFX##_iter_start, { + // WIP + cmc_assert(true); + cmc_assert(true); + }); +}); #ifdef CMC_TEST_MAIN int main(void) diff --git a/tests/main/unt/heap.c b/tests/main/unt/heap.c index dcf7e9e..94f2fa8 100644 --- a/tests/main/unt/heap.c +++ b/tests/main/unt/heap.c @@ -123,7 +123,6 @@ CMC_CREATE_UNIT(Heap, true, { for (size_t i = 1; i <= 100; i++) cmc_assert(h_insert(h, i)); - size_t r; size_t i = 0; size_t arr[100]; while (!h_empty(h)) diff --git a/tests/main/unt/utl.c b/tests/main/unt/utl.c index 591157e..391e3b4 100644 --- a/tests/main/unt/utl.c +++ b/tests/main/unt/utl.c @@ -16,16 +16,19 @@ size_t numhash(size_t a) size_t hashcapminus1(size_t a) { + (void)a; return cmc_hashtable_primes[0] - 1; } size_t hashcapminus4(size_t a) { + (void)a; return cmc_hashtable_primes[0] - 1; } size_t hash0(size_t a) { + (void)a; return 0; } @@ -65,6 +68,7 @@ bool k_c_str(FILE *fptr, size_t a) void k_c_free(size_t a) { + (void)a; k_total_free++; } @@ -103,6 +107,7 @@ bool v_c_str(FILE *fptr, size_t a) void v_c_free(size_t a) { + (void)a; v_total_free++; } diff --git a/tests/to_string.c b/tests/to_string.c index 4f37d45..a4e91f7 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -16,6 +16,8 @@ C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q, queue, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl, sortedlist, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s, stack, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm, treemap, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts, treeset, , , int)) struct { @@ -49,6 +51,9 @@ int main(void) struct queue *q = q_new(100, (struct queue_fval *)&int_ftab); struct sortedlist *sl = sl_new(100, (struct sortedlist_fval *)&int_ftab); struct stack *s = s_new(100, (struct stack_fval *)&int_ftab); + struct treemap *tm = tm_new((struct treemap_fkey *)&int_ftab, + (struct treemap_fval *)&int_ftab); + struct treeset *ts = ts_new((struct treeset_fval *)&int_ftab); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -76,6 +81,10 @@ int main(void) sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); s_to_string(s, stdout); s_print(s, stdout, "\n[ ", ", ", " ]\n"); + tm_to_string(tm, stdout); + tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + ts_to_string(ts, stdout); + ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); fprintf(stdout, "\n"); @@ -92,6 +101,8 @@ int main(void) q_enqueue(q, 0); sl_insert(sl, 0); s_push(s, 0); + tm_insert(tm, 0, 0); + ts_insert(ts, 0); d_to_string(d, stdout); d_print(d, stdout, "\n[ ", ", ", " ]\n"); @@ -119,6 +130,10 @@ int main(void) sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); s_to_string(s, stdout); s_print(s, stdout, "\n[ ", ", ", " ]\n"); + tm_to_string(tm, stdout); + tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + ts_to_string(ts, stdout); + ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); for (int i = 1; i < 20; i++) { @@ -135,6 +150,8 @@ int main(void) q_enqueue(q, i); sl_insert(sl, i); s_push(s, i); + tm_insert(tm, i, i); + ts_insert(ts, i); } fprintf(stdout, "\n"); @@ -165,6 +182,10 @@ int main(void) sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); s_to_string(s, stdout); s_print(s, stdout, "\n[ ", ", ", " ]\n"); + tm_to_string(tm, stdout); + tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); + ts_to_string(ts, stdout); + ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); d_free(d); hbm_free(hbm); @@ -178,6 +199,9 @@ int main(void) l_free(l); q_free(q); sl_free(sl); + s_free(s); + tm_free(tm); + ts_free(ts); } // clang-format on From f8607e8cdcb916167e02799d1935ecb6ababe100 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 11 Jun 2020 00:39:56 -0300 Subject: [PATCH 29/51] Now it is possible to have opaque collections PUBLIC and PRIVATE are back --- src/cmc/bitset.h | 37 +++++++++++++++++++++++++++++++----- src/cmc/deque.h | 40 ++++++++++++++++++++++++++++++--------- src/cmc/hashbidimap.h | 39 +++++++++++++++++++++++++++++++++----- src/cmc/hashmap.h | 42 ++++++++++++++++++++++++++++++++++------- src/cmc/hashmultimap.h | 39 +++++++++++++++++++++++++++++++++----- src/cmc/hashmultiset.h | 38 ++++++++++++++++++++++++++++++++----- src/cmc/hashset.h | 37 +++++++++++++++++++++++++++++++----- src/cmc/heap.h | 36 ++++++++++++++++++++++++++++++----- src/cmc/intervalheap.h | 37 +++++++++++++++++++++++++++++++----- src/cmc/linkedlist.h | 37 +++++++++++++++++++++++++++++++----- src/cmc/list.h | 36 ++++++++++++++++++++++++++++++----- src/cmc/queue.h | 36 ++++++++++++++++++++++++++++++----- src/cmc/sortedlist.h | 37 +++++++++++++++++++++++++++++++----- src/cmc/stack.h | 36 ++++++++++++++++++++++++++++++----- src/cmc/treemap.h | 38 ++++++++++++++++++++++++++++++++----- src/cmc/treeset.h | 36 ++++++++++++++++++++++++++++++----- src/cor/core.h | 9 --------- src/cor/flags.h | 6 ++++-- src/macro_collections.h | 8 ++++---- tests/to_string.c | 1 + 20 files changed, 524 insertions(+), 101 deletions(-) diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index 6872533..9dff4a7 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -43,19 +43,39 @@ /** * Core BitSet implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_BITSET_CORE(PARAMS) \ - CMC_CMC_BITSET_CORE_HEADER(PARAMS) \ +#define CMC_CMC_BITSET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_BITSET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_BITSET_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_BITSET_CORE_STRUCT(PARAMS) \ + CMC_CMC_BITSET_CORE_HEADER(PARAMS) + +#define CMC_CMC_BITSET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_BITSET_CORE_SOURCE(PARAMS) + +#define CMC_CMC_BITSET_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_BITSET_CORE_HEADER(PARAMS) + +#define CMC_CMC_BITSET_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_BITSET_CORE_STRUCT(PARAMS) \ CMC_CMC_BITSET_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_BITSET_CORE_STRUCT(PARAMS) CMC_CMC_BITSET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) + #define CMC_CMC_BITSET_CORE_HEADER(PARAMS) CMC_CMC_BITSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) #define CMC_CMC_BITSET_CORE_SOURCE(PARAMS) CMC_CMC_BITSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_BITSET_CORE_HEADER_(PFX, SNAME) \ +#define CMC_CMC_BITSET_CORE_STRUCT_(PFX, SNAME) \ \ /* BitSet Structure */ \ struct SNAME \ @@ -74,7 +94,12 @@ \ /* Custom callback functions */ \ CMC_CALLBACKS_DECL; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_BITSET_CORE_HEADER_(PFX, SNAME) \ \ /* BitSet Iterator */ \ struct CMC_DEF_ITER(SNAME) \ @@ -157,6 +182,8 @@ struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ struct CMC_CALLBACKS_NAME * callbacks) \ { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ +\ if (n_bits < 1) \ return NULL; \ \ diff --git a/src/cmc/deque.h b/src/cmc/deque.h index d2783b4..07c78ec 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -36,17 +36,34 @@ * ------------------------------------------------------------------------- */ #include "../cor/core.h" -/* ------------------------------------------------------------------------- - * Deque Specific - * ------------------------------------------------------------------------- */ - /** * Core Deque implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_DEQUE_CORE(PARAMS) \ - CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \ +#define CMC_CMC_DEQUE_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_DEQUE_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_DEQUE_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \ + CMC_CMC_DEQUE_CORE_HEADER(PARAMS) + +#define CMC_CMC_DEQUE_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) + +#define CMC_CMC_DEQUE_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_DEQUE_CORE_HEADER(PARAMS) + +#define CMC_CMC_DEQUE_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \ CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \ + CMC_CMC_DEQUE_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \ CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -54,9 +71,9 @@ CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_DEQUE_CORE_STRUCT_(PFX, SNAME, V) \ \ /* Deque Structure */ \ struct SNAME \ @@ -86,7 +103,12 @@ \ /* Custom callback functions */ \ CMC_CALLBACKS_DECL; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ \ struct CMC_DEF_FVAL(SNAME) \ { \ diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index 9a92328..9edab75 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -38,11 +38,35 @@ /** * Core HashBidiMap implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_HASHBIDIMAP_CORE(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \ +#define CMC_CMC_HASHBIDIMAP_CORE(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_CMC_HASHBIDIMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_HASHBIDIMAP_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHBIDIMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) + +#define CMC_CMC_HASHBIDIMAP_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ + CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHBIDIMAP_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \ CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHBIDIMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + #define CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \ CMC_CMC_HASHBIDIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) @@ -52,9 +76,9 @@ CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHBIDIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ +#define CMC_CMC_HASHBIDIMAP_CORE_STRUCT_(PFX, SNAME, K, V) \ \ /* HashBidiMap Structure */ \ struct SNAME \ @@ -114,7 +138,12 @@ /* ref[0] is relative to K -> V */ \ /* ref[1] is relative to V -> K */ \ struct CMC_DEF_ENTRY(SNAME) * *ref[2]; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_HASHBIDIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ \ /* Key struct function table */ \ struct CMC_DEF_FKEY(SNAME) \ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index c0e2e06..73d71cd 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -31,11 +31,34 @@ /** * Core HashMap implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_HASHMAP_CORE(PARAMS) \ - CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \ +#define CMC_CMC_HASHMAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HASHMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_HASHMAP_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) + +#define CMC_CMC_HASHMAP_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ + CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHMAP_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \ CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + #define CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \ CMC_CMC_HASHMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) @@ -45,11 +68,11 @@ CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \ +#define CMC_CMC_HASHMAP_CORE_STRUCT_(PFX, SNAME, K, V) \ \ - /* Hashmap Structure */ \ + /* HashMap Structure */ \ struct SNAME \ { \ /* Array of Entries */ \ @@ -80,7 +103,7 @@ CMC_CALLBACKS_DECL; \ }; \ \ - /* Hashmap Entry */ \ + /* HashMap Entry */ \ struct CMC_DEF_ENTRY(SNAME) \ { \ /* Entry Key */ \ @@ -95,7 +118,12 @@ \ /* The sate of this node (DELETED, EMPTY, FILLED) */ \ enum cmc_entry_state state; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \ \ /* Key struct function table */ \ struct CMC_DEF_FKEY(SNAME) \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index b6eb64e..16e20b2 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -56,11 +56,35 @@ /** * Core HashMultiMap implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_HASHMULTIMAP_CORE(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \ +#define CMC_CMC_HASHMULTIMAP_CORE(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_CMC_HASHMULTIMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_HASHMULTIMAP_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHMULTIMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) + +#define CMC_CMC_HASHMULTIMAP_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ + CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHMULTIMAP_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \ CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHMULTIMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + #define CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \ CMC_CMC_HASHMULTIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) @@ -70,9 +94,9 @@ CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ +#define CMC_CMC_HASHMULTIMAP_CORE_STRUCT_(PFX, SNAME, K, V) \ \ /* HashMultimap Structure */ \ struct SNAME \ @@ -119,7 +143,12 @@ \ /* Previous entry on the linked list */ \ struct CMC_DEF_ENTRY(SNAME) * prev; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ \ /* Key struct function table */ \ struct CMC_DEF_FKEY(SNAME) \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index 0ee8fc2..f94ac96 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -38,11 +38,34 @@ /** * Core HashMultiSet implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_HASHMULTISET_CORE(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) \ +#define CMC_CMC_HASHMULTISET_CORE(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_CMC_HASHMULTISET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_HASHMULTISET_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHMULTISET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) + +#define CMC_CMC_HASHMULTISET_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ + CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHMULTISET_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \ CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHMULTISET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) \ CMC_CMC_HASHMULTISET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -50,9 +73,9 @@ CMC_CMC_HASHMULTISET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTISET_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_HASHMULTISET_CORE_STRUCT_(PFX, SNAME, V) \ \ /* HashMultiset Structure */ \ struct SNAME \ @@ -99,7 +122,12 @@ \ /* The sate of this node (DELETED, EMPTY, FILLED) */ \ enum cmc_entry_state state; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_HASHMULTISET_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 1cc9b87..04b2c2e 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -31,11 +31,33 @@ /** * Core HashSet implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_HASHSET_CORE(PARAMS) \ - CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \ +#define CMC_CMC_HASHSET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HASHSET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_HASHSET_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHSET_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHSET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) + +#define CMC_CMC_HASHSET_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ + CMC_CMC_HASHSET_CORE_HEADER(PARAMS) + +#define CMC_CMC_HASHSET_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \ CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \ + CMC_CMC_HASHSET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \ CMC_CMC_HASHSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -43,9 +65,9 @@ CMC_CMC_HASHSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_HASHSET_CORE_STRUCT_(PFX, SNAME, V) \ \ /* Hashset Structure */ \ struct SNAME \ @@ -86,7 +108,12 @@ \ /* The sate of this node (DELETED, EMPTY, FILLED) */ \ enum cmc_entry_state state; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/heap.h b/src/cmc/heap.h index 6d0d19e..aa654d6 100644 --- a/src/cmc/heap.h +++ b/src/cmc/heap.h @@ -42,11 +42,32 @@ /** * Core Heap implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_HEAP_CORE(PARAMS) \ - CMC_CMC_HEAP_CORE_HEADER(PARAMS) \ +#define CMC_CMC_HEAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HEAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_HEAP_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_HEAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_HEAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HEAP_CORE_SOURCE(PARAMS) + +#define CMC_CMC_HEAP_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_HEAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_HEAP_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \ CMC_CMC_HEAP_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_HEAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_HEAP_CORE_HEADER(PARAMS) \ CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -54,9 +75,9 @@ CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_HEAP_CORE_STRUCT_(PFX, SNAME, V) \ \ /* Heap Structure */ \ struct SNAME \ @@ -84,7 +105,12 @@ \ /* Custom callback functions */ \ CMC_CALLBACKS_DECL; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h index ac82682..4094108 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc/intervalheap.h @@ -28,11 +28,33 @@ /** * Core IntervalHeap implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_INTERVALHEAP_CORE(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) \ +#define CMC_CMC_INTERVALHEAP_CORE(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_CMC_INTERVALHEAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_INTERVALHEAP_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_INTERVALHEAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) + +#define CMC_CMC_INTERVALHEAP_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_INTERVALHEAP_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \ CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_INTERVALHEAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) \ CMC_CMC_INTERVALHEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -40,9 +62,9 @@ CMC_CMC_INTERVALHEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_INTERVALHEAP_CORE_STRUCT_(PFX, SNAME, V) \ \ /* IntervalHeap Structure */ \ struct SNAME \ @@ -71,7 +93,12 @@ \ /* Custom callback functions */ \ CMC_CALLBACKS_DECL; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h index af1f82c..88479a0 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc/linkedlist.h @@ -35,11 +35,33 @@ /** * Core LinkedList implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_LINKEDLIST_CORE(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) \ +#define CMC_CMC_LINKEDLIST_CORE(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_CMC_LINKEDLIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_LINKEDLIST_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \ + CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) + +#define CMC_CMC_LINKEDLIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) + +#define CMC_CMC_LINKEDLIST_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) + +#define CMC_CMC_LINKEDLIST_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \ CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \ + CMC_CMC_LINKEDLIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) \ CMC_CMC_LINKEDLIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -47,9 +69,9 @@ CMC_CMC_LINKEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_LINKEDLIST_CORE_STRUCT_(PFX, SNAME, V) \ \ /* Linked List Structure */ \ struct SNAME \ @@ -87,7 +109,12 @@ \ /* Pointer to the previous node on the linked list */ \ struct CMC_DEF_NODE(SNAME) * prev; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/list.h b/src/cmc/list.h index 1e67123..c98fe87 100644 --- a/src/cmc/list.h +++ b/src/cmc/list.h @@ -50,11 +50,32 @@ /** * Core List implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_LIST_CORE(PARAMS) \ - CMC_CMC_LIST_CORE_HEADER(PARAMS) \ +#define CMC_CMC_LIST_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_LIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_LIST_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_LIST_CORE_STRUCT(PARAMS) \ + CMC_CMC_LIST_CORE_HEADER(PARAMS) + +#define CMC_CMC_LIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_LIST_CORE_SOURCE(PARAMS) + +#define CMC_CMC_LIST_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_LIST_CORE_HEADER(PARAMS) + +#define CMC_CMC_LIST_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_LIST_CORE_STRUCT(PARAMS) \ CMC_CMC_LIST_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_LIST_CORE_STRUCT(PARAMS) \ + CMC_CMC_LIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_LIST_CORE_HEADER(PARAMS) \ CMC_CMC_LIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -62,9 +83,9 @@ CMC_CMC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_LIST_CORE_STRUCT_(PFX, SNAME, V) \ \ /* List Structure */ \ struct SNAME \ @@ -89,7 +110,12 @@ \ /* Custom callback functions */ \ CMC_CALLBACKS_DECL; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/queue.h b/src/cmc/queue.h index abbc466..3e47e99 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -50,11 +50,32 @@ /** * Core Queue implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_QUEUE_CORE(PARAMS) \ - CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \ +#define CMC_CMC_QUEUE_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_QUEUE_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_QUEUE_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \ + CMC_CMC_QUEUE_CORE_HEADER(PARAMS) + +#define CMC_CMC_QUEUE_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) + +#define CMC_CMC_QUEUE_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_QUEUE_CORE_HEADER(PARAMS) + +#define CMC_CMC_QUEUE_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \ CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \ + CMC_CMC_QUEUE_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \ CMC_CMC_QUEUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -62,9 +83,9 @@ CMC_CMC_QUEUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_QUEUE_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_QUEUE_CORE_STRUCT_(PFX, SNAME, V) \ \ /* Queue Structure */ \ struct SNAME \ @@ -95,7 +116,12 @@ \ /* Custom callback functions */ \ CMC_CALLBACKS_DECL; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_QUEUE_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h index 34879ed..5f36f32 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc/sortedlist.h @@ -29,11 +29,33 @@ /** * Core SortedList implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_SORTEDLIST_CORE(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) \ +#define CMC_CMC_SORTEDLIST_CORE(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_CMC_SORTEDLIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_SORTEDLIST_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \ + CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) + +#define CMC_CMC_SORTEDLIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) + +#define CMC_CMC_SORTEDLIST_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) + +#define CMC_CMC_SORTEDLIST_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \ CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \ + CMC_CMC_SORTEDLIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) \ CMC_CMC_SORTEDLIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -41,9 +63,9 @@ CMC_CMC_SORTEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_SORTEDLIST_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_SORTEDLIST_CORE_STRUCT_(PFX, SNAME, V) \ \ /* List Structure */ \ struct SNAME \ @@ -71,7 +93,12 @@ \ /* Custom callback functions */ \ CMC_CALLBACKS_DECL; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_SORTEDLIST_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/stack.h b/src/cmc/stack.h index 09a1bc4..a5e9527 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -35,11 +35,32 @@ /** * Core Stack implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_STACK_CORE(PARAMS) \ - CMC_CMC_STACK_CORE_HEADER(PARAMS) \ +#define CMC_CMC_STACK_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_STACK_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_STACK_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_STACK_CORE_STRUCT(PARAMS) \ + CMC_CMC_STACK_CORE_HEADER(PARAMS) + +#define CMC_CMC_STACK_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_STACK_CORE_SOURCE(PARAMS) + +#define CMC_CMC_STACK_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_STACK_CORE_HEADER(PARAMS) + +#define CMC_CMC_STACK_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_STACK_CORE_STRUCT(PARAMS) \ CMC_CMC_STACK_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_STACK_CORE_STRUCT(PARAMS) \ + CMC_CMC_STACK_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_STACK_CORE_HEADER(PARAMS) \ CMC_CMC_STACK_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -47,9 +68,9 @@ CMC_CMC_STACK_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_STACK_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_STACK_CORE_STRUCT_(PFX, SNAME, V) \ \ /* Stack Structure */ \ struct SNAME \ @@ -74,7 +95,12 @@ \ /* Custom callback functions */ \ CMC_CALLBACKS_DECL; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_STACK_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index 3464bd5..f3580bf 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -26,11 +26,34 @@ /** * Core TreeMap implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_TREEMAP_CORE(PARAMS) \ - CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \ +#define CMC_CMC_TREEMAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_TREEMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_TREEMAP_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_TREEMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) + +#define CMC_CMC_TREEMAP_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + struct CMC_DEF_NODE(CMC_PARAM_SNAME(PARAMS)); \ + CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) + +#define CMC_CMC_TREEMAP_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \ CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \ + CMC_CMC_TREEMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + #define CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \ CMC_CMC_TREEMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) @@ -40,9 +63,9 @@ CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREEMAP_CORE_HEADER_(PFX, SNAME, K, V) \ +#define CMC_CMC_TREEMAP_CORE_STRUCT_(PFX, SNAME, K, V) \ \ /* Treemap Structure */ \ struct SNAME \ @@ -89,7 +112,12 @@ \ /* Parent node */ \ struct CMC_DEF_NODE(SNAME) * parent; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_TREEMAP_CORE_HEADER_(PFX, SNAME, K, V) \ \ /* Key struct function table */ \ struct CMC_DEF_FKEY(SNAME) \ diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 7219092..9b9ed6c 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -26,11 +26,32 @@ /** * Core TreeSet implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_CMC_TREESET_CORE(PARAMS) \ - CMC_CMC_TREESET_CORE_HEADER(PARAMS) \ +#define CMC_CMC_TREESET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_TREESET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_CMC_TREESET_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \ + CMC_CMC_TREESET_CORE_HEADER(PARAMS) + +#define CMC_CMC_TREESET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_TREESET_CORE_SOURCE(PARAMS) + +#define CMC_CMC_TREESET_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_CMC_TREESET_CORE_HEADER(PARAMS) + +#define CMC_CMC_TREESET_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \ CMC_CMC_TREESET_CORE_SOURCE(PARAMS) +/* Lowest level API */ +#define CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \ + CMC_CMC_TREESET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + #define CMC_CMC_TREESET_CORE_HEADER(PARAMS) \ CMC_CMC_TREESET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -38,9 +59,9 @@ CMC_CMC_TREESET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) /* ------------------------------------------------------------------------- - * Header + * Struct * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREESET_CORE_HEADER_(PFX, SNAME, V) \ +#define CMC_CMC_TREESET_CORE_STRUCT_(PFX, SNAME, V) \ \ /* Treeset Structure */ \ struct SNAME \ @@ -81,7 +102,12 @@ \ /* Parent node */ \ struct CMC_DEF_NODE(SNAME) * parent; \ - }; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_CMC_TREESET_CORE_HEADER_(PFX, SNAME, V) \ \ /* Value struct function table */ \ struct CMC_DEF_FVAL(SNAME) \ diff --git a/src/cor/core.h b/src/cor/core.h index dc0f400..430d35d 100644 --- a/src/cor/core.h +++ b/src/cor/core.h @@ -98,13 +98,4 @@ #define CMC_PARAM_K CMC_TUP_3 #define CMC_PARAM_V CMC_TUP_4 -/** - * Marks a function parameter used or unused depending on the expanded value of - * MACRO. It need to expand to either TRUE or FALSE. - */ -#define CMC_UNUSED_PARAM(MACRO, PARAM) CMC_(CMC_UNUSED_PARAM_, MACRO)(PARAM) - -#define CMC_UNUSED_PARAM_FALSE(PARAM) PARAM -#define CMC_UNUSED_PARAM_TRUE(PARAM) - #endif /* CMC_COR_CORE_H */ diff --git a/src/cor/flags.h b/src/cor/flags.h index e080a53..0a39e02 100644 --- a/src/cor/flags.h +++ b/src/cor/flags.h @@ -11,6 +11,8 @@ #ifndef CMC_COR_FLAGS_H #define CMC_COR_FLAGS_H +#include "core.h" + /** * enum cmc_flags * @@ -37,7 +39,7 @@ enum cmc_flags * * Maps the error codes to their character representation. */ -const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID", - "RANGE", "DUPLICATE", "ERROR", "THREAD", "MUTEX" }; +CMC_UNUSED static const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID", + "RANGE", "DUPLICATE", "ERROR", "THREAD", "MUTEX" }; #endif /* CMC_COR_FLAGS_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index a19ff94..b6d91c4 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -121,7 +121,7 @@ * \param PARTS A non-empty tuple of all desired EXT parts */ #define C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, HEADER, PARAMS) \ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, CMC_EVAL PARTS) /** @@ -135,7 +135,7 @@ * \param PARTS A non-empty tuple of all desired EXT parts */ #define C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, SOURCE, PARAMS) \ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, CMC_EVAL PARTS) /** @@ -162,7 +162,7 @@ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V */ #define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, HEADER, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, HEADER, PARAMS) \ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) /** @@ -175,7 +175,7 @@ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V */ #define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, SOURCE, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, SOURCE, PARAMS) \ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) /** diff --git a/tests/to_string.c b/tests/to_string.c index a4e91f7..df8b926 100644 --- a/tests/to_string.c +++ b/tests/to_string.c @@ -3,6 +3,7 @@ #include "macro_collections.h" // clang-format off +C_MACRO_COLLECTIONS_ALL(CMC, BITSET, ( bs, bitset, , , )) C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm, hashbidimap, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) From 4bebb90cb6f363c038d1584f9b653f9aa265bf47 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 11 Jun 2020 21:23:42 -0300 Subject: [PATCH 30/51] Tests reworked - CI might not work --- .gitignore | 3 + .travis.yml | 3 +- Makefile | 94 ++++++++- autogen.py | 182 ++++++++++++++---- src/cmc/stack.h | 2 +- tests/Makefile | 22 --- tests/README.md | 9 - tests/include/cmc/bitset.h | 51 +++++ tests/include/cmc/deque.h | 78 ++++++++ tests/include/cmc/hashbidimap.h | 101 ++++++++++ tests/include/cmc/hashmap.h | 100 ++++++++++ tests/include/cmc/hashmultimap.h | 102 ++++++++++ tests/include/cmc/hashmultiset.h | 98 ++++++++++ tests/include/cmc/hashset.h | 88 +++++++++ tests/include/cmc/heap.h | 68 +++++++ tests/include/cmc/intervalheap.h | 72 +++++++ tests/include/cmc/linkedlist.h | 92 +++++++++ tests/include/cmc/list.h | 82 ++++++++ tests/include/cmc/queue.h | 71 +++++++ tests/include/cmc/sortedlist.h | 72 +++++++ tests/include/cmc/stack.h | 68 +++++++ tests/include/cmc/treemap.h | 92 +++++++++ tests/include/cmc/treeset.h | 84 ++++++++ tests/main.c | 102 ++++++++++ tests/main/Makefile | 107 ---------- tests/main/README.md | 3 - tests/main/main.c | 96 --------- tests/sep/Makefile | 15 -- tests/sep/collections.c | 17 -- tests/sep/collections.h | 17 -- tests/sep/main.c | 62 ------ tests/{main/src => src/cmc}/bitset.c | 48 +---- tests/{main/src => src/cmc}/deque.c | 74 ------- tests/{main/src => src/cmc}/hashbidimap.c | 97 ---------- tests/{main/src => src/cmc}/hashmap.c | 96 --------- tests/{main/src => src/cmc}/hashmultimap.c | 98 ---------- tests/{main/src => src/cmc}/hashmultiset.c | 94 --------- tests/{main/src => src/cmc}/hashset.c | 84 -------- tests/{main/src => src/cmc}/heap.c | 64 ------ tests/{main/src => src/cmc}/intervalheap.c | 68 ------- tests/{main/src => src/cmc}/linkedlist.c | 88 --------- tests/{main/src => src/cmc}/list.c | 78 -------- tests/{main/src => src/cmc}/queue.c | 67 ------- tests/{main/src => src/cmc}/sortedlist.c | 68 ------- tests/{main/src => src/cmc}/stack.c | 66 +------ tests/{main/src => src/cmc}/treemap.c | 88 --------- tests/{main/src => src/cmc}/treeset.c | 80 -------- tests/{main/unt/bitset.c => unt/cmc/bitset.h} | 34 ++-- tests/{main/unt/deque.c => unt/cmc/deque.h} | 172 +++++++++-------- .../hashbidimap.c => unt/cmc/hashbidimap.h} | 29 ++- .../{main/unt/hashmap.c => unt/cmc/hashmap.h} | 170 ++++++++-------- .../hashmultimap.c => unt/cmc/hashmultimap.h} | 24 ++- .../hashmultiset.c => unt/cmc/hashmultiset.h} | 24 ++- .../{main/unt/hashset.c => unt/cmc/hashset.h} | 28 +-- tests/{main/unt/heap.c => unt/cmc/heap.h} | 19 +- .../intervalheap.c => unt/cmc/intervalheap.h} | 29 ++- .../unt/linkedlist.c => unt/cmc/linkedlist.h} | 19 +- tests/{main/unt/list.c => unt/cmc/list.h} | 19 +- tests/{main/unt/queue.c => unt/cmc/queue.h} | 19 +- .../unt/sortedlist.c => unt/cmc/sortedlist.h} | 19 +- tests/{main/unt/stack.c => unt/cmc/stack.h} | 19 +- .../{main/unt/treemap.c => unt/cmc/treemap.h} | 19 +- .../{main/unt/treeset.c => unt/cmc/treeset.h} | 19 +- tests/{main/unt/utl.c => unt/utl.h} | 9 +- .../{main/unt/foreach.c => unt/utl/foreach.h} | 41 ++-- 65 files changed, 2071 insertions(+), 1952 deletions(-) delete mode 100644 tests/Makefile delete mode 100644 tests/README.md create mode 100644 tests/include/cmc/bitset.h create mode 100644 tests/include/cmc/deque.h create mode 100644 tests/include/cmc/hashbidimap.h create mode 100644 tests/include/cmc/hashmap.h create mode 100644 tests/include/cmc/hashmultimap.h create mode 100644 tests/include/cmc/hashmultiset.h create mode 100644 tests/include/cmc/hashset.h create mode 100644 tests/include/cmc/heap.h create mode 100644 tests/include/cmc/intervalheap.h create mode 100644 tests/include/cmc/linkedlist.h create mode 100644 tests/include/cmc/list.h create mode 100644 tests/include/cmc/queue.h create mode 100644 tests/include/cmc/sortedlist.h create mode 100644 tests/include/cmc/stack.h create mode 100644 tests/include/cmc/treemap.h create mode 100644 tests/include/cmc/treeset.h create mode 100644 tests/main.c delete mode 100644 tests/main/Makefile delete mode 100644 tests/main/README.md delete mode 100644 tests/main/main.c delete mode 100644 tests/sep/Makefile delete mode 100644 tests/sep/collections.c delete mode 100644 tests/sep/collections.h delete mode 100644 tests/sep/main.c rename tests/{main/src => src/cmc}/bitset.c (83%) rename tests/{main/src => src/cmc}/deque.c (83%) rename tests/{main/src => src/cmc}/hashbidimap.c (86%) rename tests/{main/src => src/cmc}/hashmap.c (85%) rename tests/{main/src => src/cmc}/hashmultimap.c (86%) rename tests/{main/src => src/cmc}/hashmultiset.c (86%) rename tests/{main/src => src/cmc}/hashset.c (86%) rename tests/{main/src => src/cmc}/heap.c (82%) rename tests/{main/src => src/cmc}/intervalheap.c (86%) rename tests/{main/src => src/cmc}/linkedlist.c (81%) rename tests/{main/src => src/cmc}/list.c (84%) rename tests/{main/src => src/cmc}/queue.c (82%) rename tests/{main/src => src/cmc}/sortedlist.c (83%) rename tests/{main/src => src/cmc}/stack.c (79%) rename tests/{main/src => src/cmc}/treemap.c (87%) rename tests/{main/src => src/cmc}/treeset.c (88%) rename tests/{main/unt/bitset.c => unt/cmc/bitset.h} (91%) rename tests/{main/unt/deque.c => unt/cmc/deque.h} (90%) rename tests/{main/unt/hashbidimap.c => unt/cmc/hashbidimap.h} (96%) rename tests/{main/unt/hashmap.c => unt/cmc/hashmap.h} (87%) rename tests/{main/unt/hashmultimap.c => unt/cmc/hashmultimap.h} (97%) rename tests/{main/unt/hashmultiset.c => unt/cmc/hashmultiset.h} (97%) rename tests/{main/unt/hashset.c => unt/cmc/hashset.h} (97%) rename tests/{main/unt/heap.c => unt/cmc/heap.h} (98%) rename tests/{main/unt/intervalheap.c => unt/cmc/intervalheap.h} (96%) rename tests/{main/unt/linkedlist.c => unt/cmc/linkedlist.h} (98%) rename tests/{main/unt/list.c => unt/cmc/list.h} (98%) rename tests/{main/unt/queue.c => unt/cmc/queue.h} (98%) rename tests/{main/unt/sortedlist.c => unt/cmc/sortedlist.h} (97%) rename tests/{main/unt/stack.c => unt/cmc/stack.h} (98%) rename tests/{main/unt/treemap.c => unt/cmc/treemap.h} (98%) rename tests/{main/unt/treeset.c => unt/cmc/treeset.h} (97%) rename tests/{main/unt/utl.c => unt/utl.h} (95%) rename tests/{main/unt/foreach.c => unt/utl/foreach.h} (97%) diff --git a/.gitignore b/.gitignore index a2d2de1..d755066 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,6 @@ dkms.conf # Experimental folder experimental/ + +# Test / Code Coverage build folder +build diff --git a/.travis.yml b/.travis.yml index ff0bf29..d7ffa96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ addons: script: - sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc - export CC=gcc-7 -# - make -C ./tests/ - - make -C ./tests/main/ + - make coverage after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/Makefile b/Makefile index ecbba47..a1c1c2a 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,95 @@ -# This file is useful to format all the source files and header in this library using clang-format +# This file was generated by a Python script +CC = gcc +CFLAGS = -std=c11 -Wall -Wextra +CFLAGS += -Wno-missing-braces -DCMC_TEST_COLOR +CVFLAGS = --coverage -O0 -g3 +INCLUDE = ./tests/include -I src -ARGS = --verbose +# Runs the script to update tests, run all tests and code coverage +all: script coverage -all: src tests +tests: script build + ./tests/main.exe -src: FORCE +# Like build but with coverage +coverage: ./tests/build/obj/cmc/bitset.o ./tests/build/obj/cmc/deque.o ./tests/build/obj/cmc/hashbidimap.o ./tests/build/obj/cmc/hashmap.o ./tests/build/obj/cmc/hashmultimap.o ./tests/build/obj/cmc/hashmultiset.o ./tests/build/obj/cmc/hashset.o ./tests/build/obj/cmc/heap.o ./tests/build/obj/cmc/intervalheap.o ./tests/build/obj/cmc/linkedlist.o ./tests/build/obj/cmc/list.o ./tests/build/obj/cmc/queue.o ./tests/build/obj/cmc/sortedlist.o ./tests/build/obj/cmc/stack.o ./tests/build/obj/cmc/treemap.o ./tests/build/obj/cmc/treeset.o ./tests/build/obj/main.o + $(CC) $^ -o ./tests/main.exe $(CFLAGS) $(CVFLAGS) + ./tests/main.exe + gcov ./tests/build/obj/main.o ./tests/build/obj/cmc/bitset.o ./tests/build/obj/cmc/deque.o ./tests/build/obj/cmc/hashbidimap.o ./tests/build/obj/cmc/hashmap.o ./tests/build/obj/cmc/hashmultimap.o ./tests/build/obj/cmc/hashmultiset.o ./tests/build/obj/cmc/hashset.o ./tests/build/obj/cmc/heap.o ./tests/build/obj/cmc/intervalheap.o ./tests/build/obj/cmc/linkedlist.o ./tests/build/obj/cmc/list.o ./tests/build/obj/cmc/queue.o ./tests/build/obj/cmc/sortedlist.o ./tests/build/obj/cmc/stack.o ./tests/build/obj/cmc/treemap.o ./tests/build/obj/cmc/treeset.o + +# Run without coverage +run: build + ./tests/main.exe + +script: + python autogen.py + +clean: + find ./tests/build -type f -delete + rm *.gcov + +# No coverage build +build: ./tests/build/obj/cmc/bitset.o ./tests/build/obj/cmc/deque.o ./tests/build/obj/cmc/hashbidimap.o ./tests/build/obj/cmc/hashmap.o ./tests/build/obj/cmc/hashmultimap.o ./tests/build/obj/cmc/hashmultiset.o ./tests/build/obj/cmc/hashset.o ./tests/build/obj/cmc/heap.o ./tests/build/obj/cmc/intervalheap.o ./tests/build/obj/cmc/linkedlist.o ./tests/build/obj/cmc/list.o ./tests/build/obj/cmc/queue.o ./tests/build/obj/cmc/sortedlist.o ./tests/build/obj/cmc/stack.o ./tests/build/obj/cmc/treemap.o ./tests/build/obj/cmc/treeset.o ./tests/build/obj/main.o + $(CC) $^ -o ./tests/main.exe $(CFLAGS) + +./tests/build/obj/main.o: ./tests/main.c + $(CC) -c $^ -o $@ -I $(INCLUDE) $(CFLAGS) + +fmt_all: fmt_src fmt_tests + +fmt_src: FORCE find ./src/ -iname *.h | xargs clang-format --style=file --verbose -i -tests: FORCE +fmt_tests: FORCE find ./tests/ -iname *.c -o -iname *.h | xargs clang-format --style=file --verbose -i -FORCE: +.PHONY FORCE: + + +./tests/build/obj/cmc/bitset.o: ./tests/src/cmc/bitset.c ./tests/include/cmc/bitset.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/deque.o: ./tests/src/cmc/deque.c ./tests/include/cmc/deque.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/hashbidimap.o: ./tests/src/cmc/hashbidimap.c ./tests/include/cmc/hashbidimap.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/hashmap.o: ./tests/src/cmc/hashmap.c ./tests/include/cmc/hashmap.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/hashmultimap.o: ./tests/src/cmc/hashmultimap.c ./tests/include/cmc/hashmultimap.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/hashmultiset.o: ./tests/src/cmc/hashmultiset.c ./tests/include/cmc/hashmultiset.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/hashset.o: ./tests/src/cmc/hashset.c ./tests/include/cmc/hashset.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/heap.o: ./tests/src/cmc/heap.c ./tests/include/cmc/heap.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/intervalheap.o: ./tests/src/cmc/intervalheap.c ./tests/include/cmc/intervalheap.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/linkedlist.o: ./tests/src/cmc/linkedlist.c ./tests/include/cmc/linkedlist.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/list.o: ./tests/src/cmc/list.c ./tests/include/cmc/list.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/queue.o: ./tests/src/cmc/queue.c ./tests/include/cmc/queue.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/sortedlist.o: ./tests/src/cmc/sortedlist.c ./tests/include/cmc/sortedlist.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/stack.o: ./tests/src/cmc/stack.c ./tests/include/cmc/stack.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/treemap.o: ./tests/src/cmc/treemap.c ./tests/include/cmc/treemap.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + +./tests/build/obj/cmc/treeset.o: ./tests/src/cmc/treeset.c ./tests/include/cmc/treeset.h + $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) diff --git a/autogen.py b/autogen.py index 476ee47..ed5d58d 100644 --- a/autogen.py +++ b/autogen.py @@ -5,6 +5,11 @@ import sys import re import subprocess +# Make sure we have the specified directory +def assert_dir(dir): + if not os.path.exists(dir): + os.makedirs(dir) + # Compiler settings CC = 'gcc' INCLUDE = '-I ./src' @@ -22,10 +27,21 @@ UNIQUE_FLAG = '// C_MACRO_COLLECTIONS_CODE' TMP_FILE = './main.c' # Output directory -OUTPUT_DIR = './tests/main/src' +# In this directory it is assumed that the following files and folders are +# included: main.c, unt folder +OUTPUT_DIR = './tests' + +# All libraries +ALL_LIBS = ['CMC', 'SAC', 'TSC'] + +# Directory mapping +DIR_MAP = {'HEADER': 'include', 'SOURCE': 'src'} + +# File extension mapping +EXT_MAP = {'HEADER': 'h', 'SOURCE': 'c'} collections = [ - # type, header, pfx, sname, key, val + # header, library, collection, pfx, sname, size, key, val {'h': '"cmc/bitset.h"', 'LIB': 'CMC', 'COLLECTION': 'BITSET', 'PFX': 'bs', 'SNAME': 'bitset', 'SIZE': '', 'K': '', 'V': '' }, {'h': '"cmc/deque.h"', 'LIB': 'CMC', 'COLLECTION': 'DEQUE', 'PFX': 'd', 'SNAME': 'deque', 'SIZE': '', 'K': '', 'V': 'size_t'}, {'h': '"cmc/hashbidimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHBIDIMAP', 'PFX': 'hbm', 'SNAME': 'hashbidimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, @@ -45,55 +61,155 @@ collections = [ ] # Create output directory -if not os.path.exists(OUTPUT_DIR): - os.makedirs(OUTPUT_DIR) +assert_dir(OUTPUT_DIR) -for data in collections: - file = open(TMP_FILE, 'w') +# include and src +for dir in DIR_MAP.values(): + assert_dir(f'{OUTPUT_DIR}/{dir}') - file.write( - f''' - #include "macro_collections.h" +# For each library, create a folder for include and src +for lib in ALL_LIBS: + for dir in DIR_MAP.values(): + assert_dir(f'{OUTPUT_DIR}/{dir}/{lib.lower()}') - {UNIQUE_FLAG} +# Generate Header and Source separately +for ftype in ['HEADER', 'SOURCE']: + for data in collections: + file = open(TMP_FILE, 'w') - C_MACRO_COLLECTIONS_ALL({data['LIB']}, {data['COLLECTION']}, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) + file.write( + f''' + #include "macro_collections.h" - {UNIQUE_FLAG} - ''') + {UNIQUE_FLAG} - file.flush() - file.close() + C_MACRO_COLLECTIONS_ALL_{ftype}({data['LIB']}, {data['COLLECTION']}, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) - result = subprocess.getoutput(f'{CC} {FLAGS} {INCLUDE} {TMP_FILE}') + {UNIQUE_FLAG} + ''') - # (?s) makes '.' match anything, even '\n' - match = re.search(fr'(?s){UNIQUE_FLAG}(?P.+){UNIQUE_FLAG}', result) + file.flush() + file.close() - if match is None: - os.remove(TMP_FILE) - print('Didn\'t match FLAG. Probably because compilation failed.', file=sys.stderr) - exit(1) + result = subprocess.getoutput(f'{CC} {FLAGS} {INCLUDE} {TMP_FILE}') - file = open(f'{OUTPUT_DIR}/{data["SNAME"]}.c', 'w') + # (?s) makes '.' match anything, even '\n' + match = re.search(fr'(?s){UNIQUE_FLAG}(?P.+){UNIQUE_FLAG}', result) - file.write( - f'''#ifndef CMC_TEST_SRC_{data['COLLECTION']} - #define CMC_TEST_SRC_{data['COLLECTION']} + if match is None: + os.remove(TMP_FILE) + print('Didn\'t match FLAG. Probably because compilation failed.', file=sys.stderr) + exit(1) - #include {data["h"]}\n{match.group("code")} + file = open(f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}', 'w') - #endif /* CMC_TEST_SRC_{data['COLLECTION']} */ - ''') + if ftype == 'HEADER': + file.write( + f''' + #ifndef CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H + #define CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H - file.flush() - file.close() + #include "macro_collections.h" + {match.group('code')} - print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{data["SNAME"]}.c') + #endif /* CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H */ + ''') + else: + file.write( + f''' + #include {data["h"]} + + {match.group("code")} + ''') + + file.flush() + file.close() + + print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}') os.remove(TMP_FILE) # Format all files print('Formating files...') -subprocess.call(['clang-format', '--style=file', '-i', f'{OUTPUT_DIR}/*.c', '--verbose']) + +cmd = ['clang-format', '--style=file', '--verbose', '-i'] +dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{lib.lower()}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys() for lib in ALL_LIBS] + +cmd.extend(dirs_to_format) +subprocess.call(cmd) + +# Makefile +BUILD_DIR = f'{OUTPUT_DIR}/build' +OBJ_DIR = f'{BUILD_DIR}/obj' +INCLUDE_DIR = f"{OUTPUT_DIR}/{DIR_MAP['HEADER']}" +SRC_DIR = f"{OUTPUT_DIR}/{DIR_MAP['SOURCE']}" + +assert_dir(BUILD_DIR) +assert_dir(OBJ_DIR) + +for lib in ALL_LIBS: + assert_dir(f'{OBJ_DIR}/{lib.lower()}') + +file = open(f'Makefile', 'w') + +file.write(f'''# This file was generated by a Python script +CC = {CC} +CFLAGS = -std=c11 -Wall -Wextra +CFLAGS += -Wno-missing-braces -DCMC_TEST_COLOR +CVFLAGS = --coverage -O0 -g3 +INCLUDE = {INCLUDE_DIR} -I src + +# Runs the script to update tests, run all tests and code coverage +all: script coverage + +tests: script build +\t{OUTPUT_DIR}/main.exe + +# Like build but with coverage +coverage: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in collections])} {OBJ_DIR}/main.o +\t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) $(CVFLAGS) +\t{OUTPUT_DIR}/main.exe +\tgcov {OBJ_DIR}/main.o {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in collections])} + +# Run without coverage +run: build +\t{OUTPUT_DIR}/main.exe + +script: +\tpython autogen.py + +clean: +\tfind {BUILD_DIR} -type f -delete +\trm *.gcov + +# No coverage build +build: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in collections])} {OBJ_DIR}/main.o +\t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) + +{OBJ_DIR}/main.o: {OUTPUT_DIR}/main.c +\t$(CC) -c $^ -o $@ -I $(INCLUDE) $(CFLAGS) +''') + +# Code formatting +file.write(''' +fmt_all: fmt_src fmt_tests + +fmt_src: FORCE + find ./src/ -iname *.h | xargs clang-format --style=file --verbose -i + +fmt_tests: FORCE + find ./tests/ -iname *.c -o -iname *.h | xargs clang-format --style=file --verbose -i + +.PHONY FORCE: + +''') + +for data in collections: + file.write(f''' +{OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o: {SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c {INCLUDE_DIR}/{data['LIB'].lower()}/{data['SNAME']}.h +\t$(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) +''') + +file.close() + print('Done') diff --git a/src/cmc/stack.h b/src/cmc/stack.h index a5e9527..cb60b1e 100644 --- a/src/cmc/stack.h +++ b/src/cmc/stack.h @@ -378,7 +378,7 @@ return NULL; \ } \ \ - CMC_CALLBACKS_ASSIGN(_stack_, callbacks); \ + CMC_CALLBACKS_ASSIGN(result, _stack_->callbacks); \ \ if (_stack_->f_val->cpy) \ { \ diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index 63d94a4..0000000 --- a/tests/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -CC = gcc -CFLAGS = -std=c11 -Wall -Wextra -CFLAGS += -Wno-unused -Wno-missing-braces - -main: FORCE - $(CC) foreach.c -o foreach.exe $(CFLAGS) - ./foreach.exe - $(CC) iterators.c -o iterators.exe $(CFLAGS) - ./iterators.exe - $(CC) contains.c -o contains.exe $(CFLAGS) - ./contains.exe - $(CC) types.c -o types.exe $(CFLAGS) - ./types.exe - make -C ./sep - -dev: main - rm *.exe ./sep/*.o ./sep/*.exe - -windev: main - del *.exe .\\sep\\*.o .\\sep\\*.exe - -FORCE: diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 0755797..0000000 --- a/tests/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Tests - -* `codecov` - A stalled version for codecov; -* `main` - Unit tests for the main C Macro Collections library; -* `sep/main.c`, `sep/sep.c` and `sep/sep.h` - Tests separate header and source compilation; -* `contains.c` - Tests the `contains` function for all collections; -* `foreach.c` - Tests the ForEach macros for all collections; -* `iterators.c` - Tests all collection's iterators; -* `types.c` - Tests if all containers accept all possible C data types (struct, union, enum, pointers, function pointers) diff --git a/tests/include/cmc/bitset.h b/tests/include/cmc/bitset.h new file mode 100644 index 0000000..0918550 --- /dev/null +++ b/tests/include/cmc/bitset.h @@ -0,0 +1,51 @@ + +#ifndef CMC_CMC_BITSET_TEST_H +#define CMC_CMC_BITSET_TEST_H + +#include "macro_collections.h" + +struct bitset +{ + cmc_bitset_word *buffer; + size_t capacity; + int flag; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct bitset_iter +{ + struct bitset *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct bitset *bs_new(size_t n_bits); +struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +struct bitset bs_init(size_t n_bits); +struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void bs_free(struct bitset *_bitset_); +void bs_release(struct bitset _bitset_); +void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool bs_set(struct bitset *_bitset_, size_t bit_index); +_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to); +_Bool bs_clear(struct bitset *_bitset_, size_t bit_index); +_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to); +_Bool bs_flip(struct bitset *_bitset_, size_t bit_index); +_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to); +_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state); +_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state); +_Bool bs_set_all(struct bitset *_bitset_); +_Bool bs_clear_all(struct bitset *_bitset_); +_Bool bs_flip_all(struct bitset *_bitset_); +_Bool bs_get(struct bitset *_bitset_, size_t bit_index); +_Bool bs_resize(struct bitset *_bitset_, size_t n_bits); +static inline size_t bs_bit_to_index(size_t idx) +{ + static const size_t shift = + ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 + ? 6 + : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; + return idx >> shift; +} + +#endif /* CMC_CMC_BITSET_TEST_H */ diff --git a/tests/include/cmc/deque.h b/tests/include/cmc/deque.h new file mode 100644 index 0000000..b664e2a --- /dev/null +++ b/tests/include/cmc/deque.h @@ -0,0 +1,78 @@ + +#ifndef CMC_CMC_DEQUE_TEST_H +#define CMC_CMC_DEQUE_TEST_H + +#include "macro_collections.h" + +struct deque +{ + size_t *buffer; + size_t capacity; + size_t count; + size_t front; + size_t back; + int flag; + struct deque_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct deque_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct deque *d_new(size_t capacity, struct deque_fval *f_val); +struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void d_clear(struct deque *_deque_); +void d_free(struct deque *_deque_); +void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool d_push_front(struct deque *_deque_, size_t value); +_Bool d_push_back(struct deque *_deque_, size_t value); +_Bool d_pop_front(struct deque *_deque_); +_Bool d_pop_back(struct deque *_deque_); +size_t d_front(struct deque *_deque_); +size_t d_back(struct deque *_deque_); +_Bool d_contains(struct deque *_deque_, size_t value); +_Bool d_empty(struct deque *_deque_); +_Bool d_full(struct deque *_deque_); +size_t d_count(struct deque *_deque_); +size_t d_capacity(struct deque *_deque_); +int d_flag(struct deque *_deque_); +_Bool d_resize(struct deque *_deque_, size_t capacity); +struct deque *d_copy_of(struct deque *_deque_); +_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_); +struct deque d_init(size_t capacity, struct deque_fval *f_val); +struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void d_release(struct deque _deque_); +struct deque_iter +{ + struct deque *target; + size_t cursor; + size_t index; + _Bool start; + _Bool end; +}; +struct deque_iter d_iter_start(struct deque *target); +struct deque_iter d_iter_end(struct deque *target); +_Bool d_iter_at_start(struct deque_iter *iter); +_Bool d_iter_at_end(struct deque_iter *iter); +_Bool d_iter_to_start(struct deque_iter *iter); +_Bool d_iter_to_end(struct deque_iter *iter); +_Bool d_iter_next(struct deque_iter *iter); +_Bool d_iter_prev(struct deque_iter *iter); +_Bool d_iter_advance(struct deque_iter *iter, size_t steps); +_Bool d_iter_rewind(struct deque_iter *iter, size_t steps); +_Bool d_iter_go_to(struct deque_iter *iter, size_t index); +size_t d_iter_value(struct deque_iter *iter); +size_t *d_iter_rvalue(struct deque_iter *iter); +size_t d_iter_index(struct deque_iter *iter); +_Bool d_to_string(struct deque *_deque_, FILE *fptr); +_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_DEQUE_TEST_H */ diff --git a/tests/include/cmc/hashbidimap.h b/tests/include/cmc/hashbidimap.h new file mode 100644 index 0000000..c574437 --- /dev/null +++ b/tests/include/cmc/hashbidimap.h @@ -0,0 +1,101 @@ + +#ifndef CMC_CMC_HASHBIDIMAP_TEST_H +#define CMC_CMC_HASHBIDIMAP_TEST_H + +#include "macro_collections.h" + +struct hashbidimap +{ + struct hashbidimap_entry *(*buffer)[2]; + size_t capacity; + size_t count; + double load; + int flag; + struct hashbidimap_fkey *f_key; + struct hashbidimap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; + struct hashbidimap_iter (*it_start)(struct hashbidimap *); + struct hashbidimap_iter (*it_end)(struct hashbidimap *); +}; +struct hashbidimap_entry +{ + size_t key; + size_t value; + size_t dist[2]; + struct hashbidimap_entry **ref[2]; +}; +struct hashbidimap_fkey +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashbidimap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashbidimap_iter +{ + struct hashbidimap *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val); +struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void hbm_clear(struct hashbidimap *_map_); +void hbm_free(struct hashbidimap *_map_); +void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value); +_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key); +_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val); +_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val); +_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val); +size_t hbm_get_key(struct hashbidimap *_map_, size_t val); +size_t hbm_get_val(struct hashbidimap *_map_, size_t key); +_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key); +_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val); +_Bool hbm_empty(struct hashbidimap *_map_); +_Bool hbm_full(struct hashbidimap *_map_); +size_t hbm_count(struct hashbidimap *_map_); +size_t hbm_capacity(struct hashbidimap *_map_); +double hbm_load(struct hashbidimap *_map_); +int hbm_flag(struct hashbidimap *_map_); +_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity); +struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_); +_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_); +struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target); +void hbm_iter_free(struct hashbidimap_iter *iter); +void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target); +_Bool hbm_iter_start(struct hashbidimap_iter *iter); +_Bool hbm_iter_end(struct hashbidimap_iter *iter); +void hbm_iter_to_start(struct hashbidimap_iter *iter); +void hbm_iter_to_end(struct hashbidimap_iter *iter); +_Bool hbm_iter_next(struct hashbidimap_iter *iter); +_Bool hbm_iter_prev(struct hashbidimap_iter *iter); +_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps); +_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps); +_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); +size_t hbm_iter_key(struct hashbidimap_iter *iter); +size_t hbm_iter_value(struct hashbidimap_iter *iter); +size_t hbm_iter_index(struct hashbidimap_iter *iter); +_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr); +_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_HASHBIDIMAP_TEST_H */ diff --git a/tests/include/cmc/hashmap.h b/tests/include/cmc/hashmap.h new file mode 100644 index 0000000..5bb61eb --- /dev/null +++ b/tests/include/cmc/hashmap.h @@ -0,0 +1,100 @@ + +#ifndef CMC_CMC_HASHMAP_TEST_H +#define CMC_CMC_HASHMAP_TEST_H + +#include "macro_collections.h" + +struct hashmap +{ + struct hashmap_entry *buffer; + size_t capacity; + size_t count; + double load; + int flag; + struct hashmap_fkey *f_key; + struct hashmap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct hashmap_entry +{ + size_t key; + size_t value; + size_t dist; + enum cmc_entry_state state; +}; +struct hashmap_fkey +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); +struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void hm_clear(struct hashmap *_map_); +void hm_free(struct hashmap *_map_); +void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); +_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value); +_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value); +_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value); +_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value); +size_t hm_get(struct hashmap *_map_, size_t key); +size_t *hm_get_ref(struct hashmap *_map_, size_t key); +_Bool hm_contains(struct hashmap *_map_, size_t key); +_Bool hm_empty(struct hashmap *_map_); +_Bool hm_full(struct hashmap *_map_); +size_t hm_count(struct hashmap *_map_); +size_t hm_capacity(struct hashmap *_map_); +double hm_load(struct hashmap *_map_); +int hm_flag(struct hashmap *_map_); +_Bool hm_resize(struct hashmap *_map_, size_t capacity); +struct hashmap *hm_copy_of(struct hashmap *_map_); +_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_); +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); +struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void hm_release(struct hashmap _map_); +struct hashmap_iter +{ + struct hashmap *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashmap_iter hm_iter_start(struct hashmap *target); +struct hashmap_iter hm_iter_end(struct hashmap *target); +_Bool hm_iter_at_start(struct hashmap_iter *iter); +_Bool hm_iter_at_end(struct hashmap_iter *iter); +_Bool hm_iter_to_start(struct hashmap_iter *iter); +_Bool hm_iter_to_end(struct hashmap_iter *iter); +_Bool hm_iter_next(struct hashmap_iter *iter); +_Bool hm_iter_prev(struct hashmap_iter *iter); +_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps); +_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps); +_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index); +size_t hm_iter_key(struct hashmap_iter *iter); +size_t hm_iter_value(struct hashmap_iter *iter); +size_t *hm_iter_rvalue(struct hashmap_iter *iter); +size_t hm_iter_index(struct hashmap_iter *iter); +_Bool hm_to_string(struct hashmap *_map_, FILE *fptr); +_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_HASHMAP_TEST_H */ diff --git a/tests/include/cmc/hashmultimap.h b/tests/include/cmc/hashmultimap.h new file mode 100644 index 0000000..7b44266 --- /dev/null +++ b/tests/include/cmc/hashmultimap.h @@ -0,0 +1,102 @@ + +#ifndef CMC_CMC_HASHMULTIMAP_TEST_H +#define CMC_CMC_HASHMULTIMAP_TEST_H + +#include "macro_collections.h" + +struct hashmultimap +{ + struct hashmultimap_entry *(*buffer)[2]; + size_t capacity; + size_t count; + double load; + int flag; + struct hashmultimap_fkey *f_key; + struct hashmultimap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct hashmultimap_entry +{ + size_t key; + size_t value; + struct hashmultimap_entry *next; + struct hashmultimap_entry *prev; +}; +struct hashmultimap_fkey +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmultimap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, + struct hashmultimap_fval *f_val); +struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, + struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void hmm_clear(struct hashmultimap *_map_); +void hmm_free(struct hashmultimap *_map_); +void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value); +_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value); +size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values); +_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value); +size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values); +_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value); +_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value); +size_t hmm_get(struct hashmultimap *_map_, size_t key); +size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key); +_Bool hmm_contains(struct hashmultimap *_map_, size_t key); +_Bool hmm_empty(struct hashmultimap *_map_); +_Bool hmm_full(struct hashmultimap *_map_); +size_t hmm_count(struct hashmultimap *_map_); +size_t hmm_key_count(struct hashmultimap *_map_, size_t key); +size_t hmm_capacity(struct hashmultimap *_map_); +double hmm_load(struct hashmultimap *_map_); +int hmm_flag(struct hashmultimap *_map_); +_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity); +struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_); +_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_); +struct hashmultimap_iter +{ + struct hashmultimap *target; + struct hashmultimap_entry *curr_entry; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target); +struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target); +_Bool hmm_iter_at_start(struct hashmultimap_iter *iter); +_Bool hmm_iter_at_end(struct hashmultimap_iter *iter); +_Bool hmm_iter_to_start(struct hashmultimap_iter *iter); +_Bool hmm_iter_to_end(struct hashmultimap_iter *iter); +_Bool hmm_iter_next(struct hashmultimap_iter *iter); +_Bool hmm_iter_prev(struct hashmultimap_iter *iter); +_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps); +_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps); +_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index); +size_t hmm_iter_key(struct hashmultimap_iter *iter); +size_t hmm_iter_value(struct hashmultimap_iter *iter); +size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter); +size_t hmm_iter_index(struct hashmultimap_iter *iter); +_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr); +_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_HASHMULTIMAP_TEST_H */ diff --git a/tests/include/cmc/hashmultiset.h b/tests/include/cmc/hashmultiset.h new file mode 100644 index 0000000..6ab4627 --- /dev/null +++ b/tests/include/cmc/hashmultiset.h @@ -0,0 +1,98 @@ + +#ifndef CMC_CMC_HASHMULTISET_TEST_H +#define CMC_CMC_HASHMULTISET_TEST_H + +#include "macro_collections.h" + +struct hashmultiset +{ + struct hashmultiset_entry *buffer; + size_t capacity; + size_t count; + size_t cardinality; + double load; + int flag; + struct hashmultiset_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct hashmultiset_entry +{ + size_t value; + size_t multiplicity; + size_t dist; + enum cmc_entry_state state; +}; +struct hashmultiset_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val); +struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void hms_clear(struct hashmultiset *_set_); +void hms_free(struct hashmultiset *_set_); +void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hms_insert(struct hashmultiset *_set_, size_t value); +_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count); +_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity); +_Bool hms_remove(struct hashmultiset *_set_, size_t value); +size_t hms_remove_all(struct hashmultiset *_set_, size_t value); +_Bool hms_max(struct hashmultiset *_set_, size_t *value); +_Bool hms_min(struct hashmultiset *_set_, size_t *value); +size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value); +_Bool hms_contains(struct hashmultiset *_set_, size_t value); +_Bool hms_empty(struct hashmultiset *_set_); +_Bool hms_full(struct hashmultiset *_set_); +size_t hms_count(struct hashmultiset *_set_); +size_t hms_cardinality(struct hashmultiset *_set_); +size_t hms_capacity(struct hashmultiset *_set_); +double hms_load(struct hashmultiset *_set_); +int hms_flag(struct hashmultiset *_set_); +_Bool hms_resize(struct hashmultiset *_set_, size_t capacity); +struct hashmultiset *hms_copy_of(struct hashmultiset *_set_); +_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset_iter +{ + struct hashmultiset *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashmultiset_iter hms_iter_start(struct hashmultiset *target); +struct hashmultiset_iter hms_iter_end(struct hashmultiset *target); +_Bool hms_iter_at_start(struct hashmultiset_iter *iter); +_Bool hms_iter_at_end(struct hashmultiset_iter *iter); +_Bool hms_iter_to_start(struct hashmultiset_iter *iter); +_Bool hms_iter_to_end(struct hashmultiset_iter *iter); +_Bool hms_iter_next(struct hashmultiset_iter *iter); +_Bool hms_iter_prev(struct hashmultiset_iter *iter); +_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps); +_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps); +_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index); +size_t hms_iter_value(struct hashmultiset_iter *iter); +size_t hms_iter_multiplicity(struct hashmultiset_iter *iter); +size_t hms_iter_index(struct hashmultiset_iter *iter); +struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr); +_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_HASHMULTISET_TEST_H */ diff --git a/tests/include/cmc/hashset.h b/tests/include/cmc/hashset.h new file mode 100644 index 0000000..a9ab75c --- /dev/null +++ b/tests/include/cmc/hashset.h @@ -0,0 +1,88 @@ + +#ifndef CMC_CMC_HASHSET_TEST_H +#define CMC_CMC_HASHSET_TEST_H + +#include "macro_collections.h" + +struct hashset +{ + struct hashset_entry *buffer; + size_t capacity; + size_t count; + double load; + int flag; + struct hashset_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct hashset_entry +{ + size_t value; + size_t dist; + enum cmc_entry_state state; +}; +struct hashset_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val); +struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void hs_clear(struct hashset *_set_); +void hs_free(struct hashset *_set_); +void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hs_insert(struct hashset *_set_, size_t value); +_Bool hs_remove(struct hashset *_set_, size_t value); +_Bool hs_max(struct hashset *_set_, size_t *value); +_Bool hs_min(struct hashset *_set_, size_t *value); +_Bool hs_contains(struct hashset *_set_, size_t value); +_Bool hs_empty(struct hashset *_set_); +_Bool hs_full(struct hashset *_set_); +size_t hs_count(struct hashset *_set_); +size_t hs_capacity(struct hashset *_set_); +double hs_load(struct hashset *_set_); +int hs_flag(struct hashset *_set_); +_Bool hs_resize(struct hashset *_set_, size_t capacity); +struct hashset *hs_copy_of(struct hashset *_set_); +_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_); +struct hashset_iter +{ + struct hashset *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashset_iter hs_iter_start(struct hashset *target); +struct hashset_iter hs_iter_end(struct hashset *target); +_Bool hs_iter_at_start(struct hashset_iter *iter); +_Bool hs_iter_at_end(struct hashset_iter *iter); +_Bool hs_iter_to_start(struct hashset_iter *iter); +_Bool hs_iter_to_end(struct hashset_iter *iter); +_Bool hs_iter_next(struct hashset_iter *iter); +_Bool hs_iter_prev(struct hashset_iter *iter); +_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps); +_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps); +_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index); +size_t hs_iter_value(struct hashset_iter *iter); +size_t hs_iter_index(struct hashset_iter *iter); +struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_to_string(struct hashset *_set_, FILE *fptr); +_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_HASHSET_TEST_H */ diff --git a/tests/include/cmc/heap.h b/tests/include/cmc/heap.h new file mode 100644 index 0000000..8b062f1 --- /dev/null +++ b/tests/include/cmc/heap.h @@ -0,0 +1,68 @@ + +#ifndef CMC_CMC_HEAP_TEST_H +#define CMC_CMC_HEAP_TEST_H + +#include "macro_collections.h" + +struct heap +{ + size_t *buffer; + size_t capacity; + size_t count; + enum cmc_heap_order HO; + int flag; + struct heap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct heap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val); +struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void h_clear(struct heap *_heap_); +void h_free(struct heap *_heap_); +void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool h_insert(struct heap *_heap_, size_t value); +_Bool h_remove(struct heap *_heap_); +size_t h_peek(struct heap *_heap_); +_Bool h_contains(struct heap *_heap_, size_t value); +_Bool h_empty(struct heap *_heap_); +_Bool h_full(struct heap *_heap_); +size_t h_count(struct heap *_heap_); +size_t h_capacity(struct heap *_heap_); +int h_flag(struct heap *_heap_); +_Bool h_resize(struct heap *_heap_, size_t capacity); +struct heap *h_copy_of(struct heap *_heap_); +_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_); +struct heap_iter +{ + struct heap *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct heap_iter h_iter_start(struct heap *target); +struct heap_iter h_iter_end(struct heap *target); +_Bool h_iter_at_start(struct heap_iter *iter); +_Bool h_iter_at_end(struct heap_iter *iter); +_Bool h_iter_to_start(struct heap_iter *iter); +_Bool h_iter_to_end(struct heap_iter *iter); +_Bool h_iter_next(struct heap_iter *iter); +_Bool h_iter_prev(struct heap_iter *iter); +_Bool h_iter_advance(struct heap_iter *iter, size_t steps); +_Bool h_iter_rewind(struct heap_iter *iter, size_t steps); +_Bool h_iter_go_to(struct heap_iter *iter, size_t index); +size_t h_iter_value(struct heap_iter *iter); +size_t h_iter_index(struct heap_iter *iter); +_Bool h_to_string(struct heap *_heap_, FILE *fptr); +_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_HEAP_TEST_H */ diff --git a/tests/include/cmc/intervalheap.h b/tests/include/cmc/intervalheap.h new file mode 100644 index 0000000..5bc4fb2 --- /dev/null +++ b/tests/include/cmc/intervalheap.h @@ -0,0 +1,72 @@ + +#ifndef CMC_CMC_INTERVALHEAP_TEST_H +#define CMC_CMC_INTERVALHEAP_TEST_H + +#include "macro_collections.h" + +struct intervalheap +{ + size_t (*buffer)[2]; + size_t capacity; + size_t size; + size_t count; + int flag; + struct intervalheap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct intervalheap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val); +struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void ih_clear(struct intervalheap *_heap_); +void ih_free(struct intervalheap *_heap_); +void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool ih_insert(struct intervalheap *_heap_, size_t value); +_Bool ih_remove_max(struct intervalheap *_heap_); +_Bool ih_remove_min(struct intervalheap *_heap_); +_Bool ih_update_max(struct intervalheap *_heap_, size_t value); +_Bool ih_update_min(struct intervalheap *_heap_, size_t value); +size_t ih_max(struct intervalheap *_heap_); +size_t ih_min(struct intervalheap *_heap_); +_Bool ih_contains(struct intervalheap *_heap_, size_t value); +_Bool ih_empty(struct intervalheap *_heap_); +_Bool ih_full(struct intervalheap *_heap_); +size_t ih_count(struct intervalheap *_heap_); +size_t ih_capacity(struct intervalheap *_heap_); +int ih_flag(struct intervalheap *_heap_); +_Bool ih_resize(struct intervalheap *_heap_, size_t capacity); +struct intervalheap *ih_copy_of(struct intervalheap *_heap_); +_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_); +struct intervalheap_iter +{ + struct intervalheap *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct intervalheap_iter ih_iter_start(struct intervalheap *target); +struct intervalheap_iter ih_iter_end(struct intervalheap *target); +_Bool ih_iter_at_start(struct intervalheap_iter *iter); +_Bool ih_iter_at_end(struct intervalheap_iter *iter); +_Bool ih_iter_to_start(struct intervalheap_iter *iter); +_Bool ih_iter_to_end(struct intervalheap_iter *iter); +_Bool ih_iter_next(struct intervalheap_iter *iter); +_Bool ih_iter_prev(struct intervalheap_iter *iter); +_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps); +_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps); +_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index); +size_t ih_iter_value(struct intervalheap_iter *iter); +size_t ih_iter_index(struct intervalheap_iter *iter); +_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr); +_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_INTERVALHEAP_TEST_H */ diff --git a/tests/include/cmc/linkedlist.h b/tests/include/cmc/linkedlist.h new file mode 100644 index 0000000..c06925d --- /dev/null +++ b/tests/include/cmc/linkedlist.h @@ -0,0 +1,92 @@ + +#ifndef CMC_CMC_LINKEDLIST_TEST_H +#define CMC_CMC_LINKEDLIST_TEST_H + +#include "macro_collections.h" + +struct linkedlist +{ + struct linkedlist_node *head; + struct linkedlist_node *tail; + size_t count; + int flag; + struct linkedlist_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct linkedlist_node +{ + size_t value; + struct linkedlist_node *next; + struct linkedlist_node *prev; +}; +struct linkedlist_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct linkedlist *ll_new(struct linkedlist_fval *f_val); +struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void ll_clear(struct linkedlist *_list_); +void ll_free(struct linkedlist *_list_); +void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool ll_push_front(struct linkedlist *_list_, size_t value); +_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index); +_Bool ll_push_back(struct linkedlist *_list_, size_t value); +_Bool ll_pop_front(struct linkedlist *_list_); +_Bool ll_pop_at(struct linkedlist *_list_, size_t index); +_Bool ll_pop_back(struct linkedlist *_list_); +size_t ll_front(struct linkedlist *_list_); +size_t ll_get(struct linkedlist *_list_, size_t index); +size_t *ll_get_ref(struct linkedlist *_list_, size_t index); +size_t ll_back(struct linkedlist *_list_); +_Bool ll_contains(struct linkedlist *_list_, size_t value); +_Bool ll_empty(struct linkedlist *_list_); +size_t ll_count(struct linkedlist *_list_); +int ll_flag(struct linkedlist *_list_); +struct linkedlist *ll_copy_of(struct linkedlist *_list_); +_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_); +struct linkedlist_iter +{ + struct linkedlist *target; + struct linkedlist_node *cursor; + size_t index; + _Bool start; + _Bool end; +}; +struct linkedlist_iter ll_iter_start(struct linkedlist *target); +struct linkedlist_iter ll_iter_end(struct linkedlist *target); +_Bool ll_iter_at_start(struct linkedlist_iter *iter); +_Bool ll_iter_at_end(struct linkedlist_iter *iter); +_Bool ll_iter_to_start(struct linkedlist_iter *iter); +_Bool ll_iter_to_end(struct linkedlist_iter *iter); +_Bool ll_iter_next(struct linkedlist_iter *iter); +_Bool ll_iter_prev(struct linkedlist_iter *iter); +_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps); +_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps); +_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index); +size_t ll_iter_value(struct linkedlist_iter *iter); +size_t *ll_iter_rvalue(struct linkedlist_iter *iter); +size_t ll_iter_index(struct linkedlist_iter *iter); +struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter); +struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); +void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); +struct linkedlist_node *ll_head(struct linkedlist *_list_); +struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); +struct linkedlist_node *ll_tail(struct linkedlist *_list_); +_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); +_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); +_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); +struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); +struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); +_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr); +_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_LINKEDLIST_TEST_H */ diff --git a/tests/include/cmc/list.h b/tests/include/cmc/list.h new file mode 100644 index 0000000..3a1043d --- /dev/null +++ b/tests/include/cmc/list.h @@ -0,0 +1,82 @@ + +#ifndef CMC_CMC_LIST_TEST_H +#define CMC_CMC_LIST_TEST_H + +#include "macro_collections.h" + +struct list +{ + size_t *buffer; + size_t capacity; + size_t count; + int flag; + struct list_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct list_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct list *l_new(size_t capacity, struct list_fval *f_val); +struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void l_clear(struct list *_list_); +void l_free(struct list *_list_); +void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool l_push_front(struct list *_list_, size_t value); +_Bool l_push_at(struct list *_list_, size_t value, size_t index); +_Bool l_push_back(struct list *_list_, size_t value); +_Bool l_pop_front(struct list *_list_); +_Bool l_pop_at(struct list *_list_, size_t index); +_Bool l_pop_back(struct list *_list_); +size_t l_front(struct list *_list_); +size_t l_get(struct list *_list_, size_t index); +size_t *l_get_ref(struct list *_list_, size_t index); +size_t l_back(struct list *_list_); +size_t l_index_of(struct list *_list_, size_t value, _Bool from_start); +_Bool l_contains(struct list *_list_, size_t value); +_Bool l_empty(struct list *_list_); +_Bool l_full(struct list *_list_); +size_t l_count(struct list *_list_); +_Bool l_fits(struct list *_list_, size_t size); +size_t l_capacity(struct list *_list_); +int l_flag(struct list *_list_); +_Bool l_resize(struct list *_list_, size_t capacity); +struct list *l_copy_of(struct list *_list_); +_Bool l_equals(struct list *_list1_, struct list *_list2_); +struct list_iter +{ + struct list *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct list_iter l_iter_start(struct list *target); +struct list_iter l_iter_end(struct list *target); +_Bool l_iter_at_start(struct list_iter *iter); +_Bool l_iter_at_end(struct list_iter *iter); +_Bool l_iter_to_start(struct list_iter *iter); +_Bool l_iter_to_end(struct list_iter *iter); +_Bool l_iter_next(struct list_iter *iter); +_Bool l_iter_prev(struct list_iter *iter); +_Bool l_iter_advance(struct list_iter *iter, size_t steps); +_Bool l_iter_rewind(struct list_iter *iter, size_t steps); +_Bool l_iter_go_to(struct list_iter *iter, size_t index); +size_t l_iter_value(struct list_iter *iter); +size_t *l_iter_rvalue(struct list_iter *iter); +size_t l_iter_index(struct list_iter *iter); +_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); +_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); +_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); +struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); +_Bool l_to_string(struct list *_list_, FILE *fptr); +_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_LIST_TEST_H */ diff --git a/tests/include/cmc/queue.h b/tests/include/cmc/queue.h new file mode 100644 index 0000000..33b4904 --- /dev/null +++ b/tests/include/cmc/queue.h @@ -0,0 +1,71 @@ + +#ifndef CMC_CMC_QUEUE_TEST_H +#define CMC_CMC_QUEUE_TEST_H + +#include "macro_collections.h" + +struct queue +{ + size_t *buffer; + size_t capacity; + size_t count; + size_t front; + size_t back; + int flag; + struct queue_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct queue_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct queue_iter +{ + struct queue *target; + size_t cursor; + size_t index; + _Bool start; + _Bool end; +}; +struct queue *q_new(size_t capacity, struct queue_fval *f_val); +struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void q_clear(struct queue *_queue_); +void q_free(struct queue *_queue_); +void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool q_enqueue(struct queue *_queue_, size_t value); +_Bool q_dequeue(struct queue *_queue_); +size_t q_peek(struct queue *_queue_); +_Bool q_contains(struct queue *_queue_, size_t value); +_Bool q_empty(struct queue *_queue_); +_Bool q_full(struct queue *_queue_); +size_t q_count(struct queue *_queue_); +size_t q_capacity(struct queue *_queue_); +int q_flag(struct queue *_queue_); +_Bool q_resize(struct queue *_queue_, size_t capacity); +struct queue *q_copy_of(struct queue *_queue_); +_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_); +struct queue_iter q_iter_start(struct queue *target); +struct queue_iter q_iter_end(struct queue *target); +_Bool q_iter_at_start(struct queue_iter *iter); +_Bool q_iter_at_end(struct queue_iter *iter); +_Bool q_iter_to_start(struct queue_iter *iter); +_Bool q_iter_to_end(struct queue_iter *iter); +_Bool q_iter_next(struct queue_iter *iter); +_Bool q_iter_prev(struct queue_iter *iter); +_Bool q_iter_advance(struct queue_iter *iter, size_t steps); +_Bool q_iter_rewind(struct queue_iter *iter, size_t steps); +_Bool q_iter_go_to(struct queue_iter *iter, size_t index); +size_t q_iter_value(struct queue_iter *iter); +size_t *q_iter_rvalue(struct queue_iter *iter); +size_t q_iter_index(struct queue_iter *iter); +_Bool q_to_string(struct queue *_queue_, FILE *fptr); +_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_QUEUE_TEST_H */ diff --git a/tests/include/cmc/sortedlist.h b/tests/include/cmc/sortedlist.h new file mode 100644 index 0000000..a34b155 --- /dev/null +++ b/tests/include/cmc/sortedlist.h @@ -0,0 +1,72 @@ + +#ifndef CMC_CMC_SORTEDLIST_TEST_H +#define CMC_CMC_SORTEDLIST_TEST_H + +#include "macro_collections.h" + +struct sortedlist +{ + size_t *buffer; + size_t capacity; + size_t count; + _Bool is_sorted; + int flag; + struct sortedlist_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct sortedlist_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val); +struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void sl_clear(struct sortedlist *_list_); +void sl_free(struct sortedlist *_list_); +void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool sl_insert(struct sortedlist *_list_, size_t value); +_Bool sl_remove(struct sortedlist *_list_, size_t index); +size_t sl_max(struct sortedlist *_list_); +size_t sl_min(struct sortedlist *_list_); +size_t sl_get(struct sortedlist *_list_, size_t index); +size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start); +_Bool sl_contains(struct sortedlist *_list_, size_t value); +_Bool sl_empty(struct sortedlist *_list_); +_Bool sl_full(struct sortedlist *_list_); +size_t sl_count(struct sortedlist *_list_); +size_t sl_capacity(struct sortedlist *_list_); +int sl_flag(struct sortedlist *_list_); +_Bool sl_resize(struct sortedlist *_list_, size_t capacity); +void sl_sort(struct sortedlist *_list_); +struct sortedlist *sl_copy_of(struct sortedlist *_list_); +_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_); +struct sortedlist_iter +{ + struct sortedlist *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct sortedlist_iter sl_iter_start(struct sortedlist *target); +struct sortedlist_iter sl_iter_end(struct sortedlist *target); +_Bool sl_iter_at_start(struct sortedlist_iter *iter); +_Bool sl_iter_at_end(struct sortedlist_iter *iter); +_Bool sl_iter_to_start(struct sortedlist_iter *iter); +_Bool sl_iter_to_end(struct sortedlist_iter *iter); +_Bool sl_iter_next(struct sortedlist_iter *iter); +_Bool sl_iter_prev(struct sortedlist_iter *iter); +_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps); +_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps); +_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index); +size_t sl_iter_value(struct sortedlist_iter *iter); +size_t sl_iter_index(struct sortedlist_iter *iter); +_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr); +_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_SORTEDLIST_TEST_H */ diff --git a/tests/include/cmc/stack.h b/tests/include/cmc/stack.h new file mode 100644 index 0000000..6f510d0 --- /dev/null +++ b/tests/include/cmc/stack.h @@ -0,0 +1,68 @@ + +#ifndef CMC_CMC_STACK_TEST_H +#define CMC_CMC_STACK_TEST_H + +#include "macro_collections.h" + +struct stack +{ + size_t *buffer; + size_t capacity; + size_t count; + int flag; + struct stack_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct stack_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct stack *s_new(size_t capacity, struct stack_fval *f_val); +struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void s_clear(struct stack *_stack_); +void s_free(struct stack *_stack_); +void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool s_push(struct stack *_stack_, size_t value); +_Bool s_pop(struct stack *_stack_); +size_t s_top(struct stack *_stack_); +_Bool s_contains(struct stack *_stack_, size_t value); +_Bool s_empty(struct stack *_stack_); +_Bool s_full(struct stack *_stack_); +size_t s_count(struct stack *_stack_); +size_t s_capacity(struct stack *_stack_); +int s_flag(struct stack *_stack_); +_Bool s_resize(struct stack *_stack_, size_t capacity); +struct stack *s_copy_of(struct stack *_stack_); +_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_); +struct stack_iter +{ + struct stack *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct stack_iter s_iter_start(struct stack *target); +struct stack_iter s_iter_end(struct stack *target); +_Bool s_iter_at_start(struct stack_iter *iter); +_Bool s_iter_at_end(struct stack_iter *iter); +_Bool s_iter_to_start(struct stack_iter *iter); +_Bool s_iter_to_end(struct stack_iter *iter); +_Bool s_iter_next(struct stack_iter *iter); +_Bool s_iter_prev(struct stack_iter *iter); +_Bool s_iter_advance(struct stack_iter *iter, size_t steps); +_Bool s_iter_rewind(struct stack_iter *iter, size_t steps); +_Bool s_iter_go_to(struct stack_iter *iter, size_t index); +size_t s_iter_value(struct stack_iter *iter); +size_t *s_iter_rvalue(struct stack_iter *iter); +size_t s_iter_index(struct stack_iter *iter); +_Bool s_to_string(struct stack *_stack_, FILE *fptr); +_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_STACK_TEST_H */ diff --git a/tests/include/cmc/treemap.h b/tests/include/cmc/treemap.h new file mode 100644 index 0000000..005ad91 --- /dev/null +++ b/tests/include/cmc/treemap.h @@ -0,0 +1,92 @@ + +#ifndef CMC_CMC_TREEMAP_TEST_H +#define CMC_CMC_TREEMAP_TEST_H + +#include "macro_collections.h" + +struct treemap +{ + struct treemap_node *root; + size_t count; + int flag; + struct treemap_fkey *f_key; + struct treemap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct treemap_node +{ + size_t key; + size_t value; + unsigned char height; + struct treemap_node *right; + struct treemap_node *left; + struct treemap_node *parent; +}; +struct treemap_fkey +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct treemap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val); +struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void tm_clear(struct treemap *_map_); +void tm_free(struct treemap *_map_); +void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool tm_insert(struct treemap *_map_, size_t key, size_t value); +_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value); +_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value); +_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value); +_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value); +size_t tm_get(struct treemap *_map_, size_t key); +size_t *tm_get_ref(struct treemap *_map_, size_t key); +_Bool tm_contains(struct treemap *_map_, size_t key); +_Bool tm_empty(struct treemap *_map_); +size_t tm_count(struct treemap *_map_); +int tm_flag(struct treemap *_map_); +struct treemap *tm_copy_of(struct treemap *_map_); +_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_); +struct treemap_iter +{ + struct treemap *target; + struct treemap_node *cursor; + struct treemap_node *first; + struct treemap_node *last; + size_t index; + _Bool start; + _Bool end; +}; +struct treemap_iter tm_iter_start(struct treemap *target); +struct treemap_iter tm_iter_end(struct treemap *target); +_Bool tm_iter_at_start(struct treemap_iter *iter); +_Bool tm_iter_at_end(struct treemap_iter *iter); +_Bool tm_iter_to_start(struct treemap_iter *iter); +_Bool tm_iter_to_end(struct treemap_iter *iter); +_Bool tm_iter_next(struct treemap_iter *iter); +_Bool tm_iter_prev(struct treemap_iter *iter); +_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps); +_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps); +_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index); +size_t tm_iter_key(struct treemap_iter *iter); +size_t tm_iter_value(struct treemap_iter *iter); +size_t *tm_iter_rvalue(struct treemap_iter *iter); +size_t tm_iter_index(struct treemap_iter *iter); +_Bool tm_to_string(struct treemap *_map_, FILE *fptr); +_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_TREEMAP_TEST_H */ diff --git a/tests/include/cmc/treeset.h b/tests/include/cmc/treeset.h new file mode 100644 index 0000000..432f272 --- /dev/null +++ b/tests/include/cmc/treeset.h @@ -0,0 +1,84 @@ + +#ifndef CMC_CMC_TREESET_TEST_H +#define CMC_CMC_TREESET_TEST_H + +#include "macro_collections.h" + +struct treeset +{ + struct treeset_node *root; + size_t count; + int flag; + struct treeset_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct treeset_node +{ + size_t value; + unsigned char height; + struct treeset_node *right; + struct treeset_node *left; + struct treeset_node *parent; +}; +struct treeset_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct treeset_iter +{ + struct treeset *target; + struct treeset_node *cursor; + struct treeset_node *first; + struct treeset_node *last; + size_t index; + _Bool start; + _Bool end; +}; +struct treeset *ts_new(struct treeset_fval *f_val); +struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void ts_clear(struct treeset *_set_); +void ts_free(struct treeset *_set_); +void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool ts_insert(struct treeset *_set_, size_t value); +_Bool ts_remove(struct treeset *_set_, size_t value); +_Bool ts_max(struct treeset *_set_, size_t *value); +_Bool ts_min(struct treeset *_set_, size_t *value); +_Bool ts_contains(struct treeset *_set_, size_t value); +_Bool ts_empty(struct treeset *_set_); +size_t ts_count(struct treeset *_set_); +int ts_flag(struct treeset *_set_); +struct treeset *ts_copy_of(struct treeset *_set_); +_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); +struct treeset_iter ts_iter_start(struct treeset *target); +struct treeset_iter ts_iter_end(struct treeset *target); +_Bool ts_iter_at_start(struct treeset_iter *iter); +_Bool ts_iter_at_end(struct treeset_iter *iter); +_Bool ts_iter_to_start(struct treeset_iter *iter); +_Bool ts_iter_to_end(struct treeset_iter *iter); +_Bool ts_iter_next(struct treeset_iter *iter); +_Bool ts_iter_prev(struct treeset_iter *iter); +_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps); +_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); +_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); +size_t ts_iter_value(struct treeset_iter *iter); +size_t ts_iter_index(struct treeset_iter *iter); +_Bool ts_to_string(struct treeset *_set_, FILE *fptr); +_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_TREESET_TEST_H */ diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 0000000..51de592 --- /dev/null +++ b/tests/main.c @@ -0,0 +1,102 @@ +#include +#include + +#include "unt/cmc/bitset.h" +#include "unt/cmc/deque.h" +#include "unt/cmc/hashbidimap.h" +#include "unt/cmc/hashmap.h" +#include "unt/cmc/hashmultimap.h" +#include "unt/cmc/hashmultiset.h" +#include "unt/cmc/hashset.h" +#include "unt/cmc/heap.h" +#include "unt/cmc/intervalheap.h" +#include "unt/cmc/linkedlist.h" +#include "unt/cmc/list.h" +#include "unt/cmc/queue.h" +#include "unt/cmc/sortedlist.h" +#include "unt/cmc/stack.h" +#include "unt/cmc/treemap.h" +#include "unt/cmc/treeset.h" + +#include "unt/utl/foreach.h" + +#include "utl/timer.h" +#include "utl/assert.h" + +#include "./unt/utl.h" + +#define cmc_run(unit, unit_fails, test_fails) \ + do \ + { \ + uintmax_t f = unit(); \ + if (f != 0) \ + unit_fails += 1; \ + test_fails += f; \ + } while (0) + +int main(void) +{ + // clang-format off + printf(" +---------------------------------------------------------------+\n"); + printf(" | C Macro Collections Library |\n"); + printf(" | |\n"); + printf(" | Test Suite |\n"); + printf(" | |\n"); + printf(" | https://github.com/LeoVen/C-Macro-Collections |\n"); + printf(" | Leonardo Vencovsky (leonardo.vencovsky@gmail.com) |\n"); + printf(" +---------------------------------------------------------------+\n\n"); + // clang-format on + + struct cmc_timer timer; + + cmc_timer_start(timer); + uintmax_t tests = 0, units = 0; + + cmc_run(CMCBitSet, units, tests); + cmc_run(CMCBitSetIter, units, tests); + cmc_run(CMCDeque, units, tests); + cmc_run(CMCDequeIter, units, tests); + cmc_run(CMCHashBidiMap, units, tests); + cmc_run(CMCHashBidiMapIter, units, tests); + cmc_run(CMCHashMap, units, tests); + cmc_run(CMCHashMapIter, units, tests); + cmc_run(CMCHashMultiMap, units, tests); + cmc_run(CMCHashMultiMapIter, units, tests); + cmc_run(CMCHashMultiSet, units, tests); + cmc_run(CMCHashMultiSetIter, units, tests); + cmc_run(CMCHashSet, units, tests); + cmc_run(CMCHashSetIter, units, tests); + cmc_run(CMCHeap, units, tests); + cmc_run(CMCHeapIter, units, tests); + cmc_run(CMCIntervalHeap, units, tests); + cmc_run(CMCIntervalHeapIter, units, tests); + cmc_run(CMCLinkedList, units, tests); + cmc_run(CMCLinkedListIter, units, tests); + cmc_run(CMCList, units, tests); + cmc_run(CMCListIter, units, tests); + cmc_run(CMCQueue, units, tests); + cmc_run(CMCQueueIter, units, tests); + cmc_run(CMCSortedList, units, tests); + cmc_run(CMCSortedListIter, units, tests); + cmc_run(CMCStack, units, tests); + cmc_run(CMCStackIter, units, tests); + cmc_run(CMCTreeMap, units, tests); + cmc_run(CMCTreeMapIter, units, tests); + cmc_run(CMCTreeSet, units, tests); + cmc_run(CMCTreeSetIter, units, tests); + + cmc_run(ForEach, units, tests); + + cmc_timer_stop(timer); + + printf(" +---------------------------------------------------------------+\n"); + printf(" | SUMMARY |\n"); + printf(" +---------------------------------------------------------------+\n"); + printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units); + printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests); + printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", cmc_assert_failed); + printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result); + printf(" +---------------------------------------------------------------+\n"); + + return tests; +} diff --git a/tests/main/Makefile b/tests/main/Makefile deleted file mode 100644 index f207ef3..0000000 --- a/tests/main/Makefile +++ /dev/null @@ -1,107 +0,0 @@ -CC = gcc -CFLAGS = -std=c11 -Wall -Wextra -CFLAGS += -Wno-missing-braces -DBFLAGS = -g3 -CVFLAGS = --coverage -O0 -INCLUDE = ../../src/ -UNIT = ./unt - -main: FORCE - $(CC) main.c -o main.exe $(CFLAGS) $(CVFLAGS) -I $(INCLUDE) -DCMC_TEST_COLOR - ./main.exe - gcov ./main.c - -nocov: FORCE - $(CC) main.c -o main.exe $(CFLAGS) -I $(INCLUDE) -DCMC_TEST_COLOR - ./main.exe - rm *.exe - -bare: FORCE - $(CC) main.c -o main.exe $(CFLAGS) -I $(INCLUDE) - ./main.exe - rm *.exe - -debug: FORCE - $(CC) main.c -o main.exe $(CFLAGS) -I $(INCLUDE) -DCMC_TEST_COLOR $(DBFLAGS) - -valgrind: debug - valgrind --leak-check=full ./main.exe - -all: bitset deque hashbidimap hashmap hashmultimap hashmultiset hashset heap intervalheap linkedlist list queue sortedlist stack treemap treeset foreach - rm ./main.exe - -bitset: $(UNIT)/bitset.c $(INCLUDE)/cmc/bitset.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR -DCMC_BITSET_WORD_TYPE=uint8_t - ./main.exe - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR -DCMC_BITSET_WORD_TYPE=uint16_t - ./main.exe - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR -DCMC_BITSET_WORD_TYPE=uint32_t - ./main.exe - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR -DCMC_BITSET_WORD_TYPE=uint64_t - ./main.exe - -deque: $(UNIT)/deque.c $(INCLUDE)/cmc/deque.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -hashbidimap: $(UNIT)/hashbidimap.c $(INCLUDE)/cmc/hashbidimap.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -hashmap: $(UNIT)/hashmap.c $(INCLUDE)/cmc/hashmap.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -hashmultimap: $(UNIT)/hashmultimap.c $(INCLUDE)/cmc/hashmultimap.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -hashmultiset: $(UNIT)/hashmultiset.c $(INCLUDE)/cmc/hashmultiset.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -hashset: $(UNIT)/hashset.c $(INCLUDE)/cmc/hashset.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -heap: $(UNIT)/heap.c $(INCLUDE)/cmc/heap.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -intervalheap: $(UNIT)/intervalheap.c $(INCLUDE)/cmc/intervalheap.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -linkedlist: $(UNIT)/linkedlist.c $(INCLUDE)/cmc/linkedlist.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -list: $(UNIT)/list.c $(INCLUDE)/cmc/list.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -queue: $(UNIT)/queue.c $(INCLUDE)/cmc/queue.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -sortedlist: $(UNIT)/sortedlist.c $(INCLUDE)/cmc/sortedlist.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -stack: $(UNIT)/stack.c $(INCLUDE)/cmc/stack.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -treemap: $(UNIT)/treemap.c $(INCLUDE)/cmc/treemap.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -treeset: $(UNIT)/treeset.c $(INCLUDE)/cmc/treeset.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -foreach: $(UNIT)/foreach.c $(INCLUDE)/utl/foreach.h - $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR - ./main.exe - -FORCE: diff --git a/tests/main/README.md b/tests/main/README.md deleted file mode 100644 index 9d14b3e..0000000 --- a/tests/main/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# main - -This folder hosts the main tests for the C Macro Collections Library. diff --git a/tests/main/main.c b/tests/main/main.c deleted file mode 100644 index 0f00641..0000000 --- a/tests/main/main.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "utl/timer.h" - -#include "unt/bitset.c" -#include "unt/deque.c" -#include "unt/hashbidimap.c" -#include "unt/hashmap.c" -#include "unt/hashmultimap.c" -#include "unt/hashmultiset.c" -#include "unt/hashset.c" -#include "unt/heap.c" -#include "unt/intervalheap.c" -#include "unt/linkedlist.c" -#include "unt/list.c" -#include "unt/queue.c" -#include "unt/sortedlist.c" -#include "unt/stack.c" -#include "unt/treemap.c" -#include "unt/treeset.c" - -#include "unt/foreach.c" - -#define cmc_run(unit, unit_fails, test_fails) \ - do \ - { \ - uintmax_t f = unit(); \ - if (f != 0) \ - unit_fails += 1; \ - test_fails += f; \ - } while (0) - -int main(void) -{ - // clang-format off - printf(" +---------------------------------------------------------------+\n"); - printf(" | C Macro Collections Library |\n"); - printf(" | |\n"); - printf(" | Test Suite |\n"); - printf(" | |\n"); - printf(" | https://github.com/LeoVen/C-Macro-Collections |\n"); - printf(" | Leonardo Vencovsky (leonardo.vencovsky@gmail.com) |\n"); - printf(" +---------------------------------------------------------------+\n\n"); - // clang-format on - - struct cmc_timer timer; - - cmc_timer_start(timer); - uintmax_t tests = 0, units = 0; - - cmc_run(BitSet, units, tests); - cmc_run(BitSetIter, units, tests); - cmc_run(Deque, units, tests); - cmc_run(DequeIter, units, tests); - cmc_run(HashBidiMap, units, tests); - cmc_run(HashBidiMapIter, units, tests); - cmc_run(HashMap, units, tests); - cmc_run(HashMapIter, units, tests); - cmc_run(HashMultiMap, units, tests); - cmc_run(HashMultiMapIter, units, tests); - cmc_run(HashMultiSet, units, tests); - cmc_run(HashMultiSetIter, units, tests); - cmc_run(HashSet, units, tests); - cmc_run(HashSetIter, units, tests); - cmc_run(Heap, units, tests); - cmc_run(HeapIter, units, tests); - cmc_run(IntervalHeap, units, tests); - cmc_run(IntervalHeapIter, units, tests); - cmc_run(LinkedList, units, tests); - cmc_run(LinkedListIter, units, tests); - cmc_run(List, units, tests); - cmc_run(ListIter, units, tests); - cmc_run(Queue, units, tests); - cmc_run(QueueIter, units, tests); - cmc_run(SortedList, units, tests); - cmc_run(SortedListIter, units, tests); - cmc_run(Stack, units, tests); - cmc_run(StackIter, units, tests); - cmc_run(TreeMap, units, tests); - cmc_run(TreeMapIter, units, tests); - cmc_run(TreeSet, units, tests); - cmc_run(TreeSetIter, units, tests); - - cmc_run(ForEach, units, tests); - - cmc_timer_stop(timer); - - printf(" +---------------------------------------------------------------+\n"); - printf(" | SUMMARY |\n"); - printf(" +---------------------------------------------------------------+\n"); - printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units); - printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests); - printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", cmc_assert_failed); - printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result); - printf(" +---------------------------------------------------------------+\n"); - - return tests; -} diff --git a/tests/sep/Makefile b/tests/sep/Makefile deleted file mode 100644 index 089d7b8..0000000 --- a/tests/sep/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -CC = gcc -CFLAGS = -std=c11 -Wall -Wextra -CFLAGS += -Wno-unused -Wno-missing-braces - -main: - $(CC) -c collections.c -o collections.o $(CFLAGS) - $(CC) -c main.c -o main.o $(CFLAGS) - $(CC) collections.o main.o -o sep.exe - ./sep.exe - -clean: - rm *.o - -clear: - rm *.o *.exe diff --git a/tests/sep/collections.c b/tests/sep/collections.c deleted file mode 100644 index 0063216..0000000 --- a/tests/sep/collections.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "collections.h" - -CMC_COLLECTION_GENERATE_SOURCE( BIDIMAP, bm, bmap, int, int) -CMC_COLLECTION_GENERATE_SOURCE( DEQUE, d, deque, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( HASHMAP, hm, hmap, int, int) -CMC_COLLECTION_GENERATE_SOURCE( HASHSET, hs, hset, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( HEAP, h, heap, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE(INTERVALHEAP, ih, iheap, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( LINKEDLIST, ll, linked, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( LIST, l, list, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( MULTIMAP, mm, mmap, int, int) -CMC_COLLECTION_GENERATE_SOURCE( MULTISET, ms, mset, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( QUEUE, q, queue, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( SORTEDLIST, sl, slist, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( STACK, s, stack, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( TREESET, ts, tset, /* K */, int) -CMC_COLLECTION_GENERATE_SOURCE( TREEMAP, tm, tmap, int, int) diff --git a/tests/sep/collections.h b/tests/sep/collections.h deleted file mode 100644 index 966a307..0000000 --- a/tests/sep/collections.h +++ /dev/null @@ -1,17 +0,0 @@ -#include "../../src/macro_collections.h" - -CMC_COLLECTION_GENERATE_HEADER( BIDIMAP, bm, bmap, int, int) -CMC_COLLECTION_GENERATE_HEADER( DEQUE, d, deque, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( HASHMAP, hm, hmap, int, int) -CMC_COLLECTION_GENERATE_HEADER( HASHSET, hs, hset, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( HEAP, h, heap, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER(INTERVALHEAP, ih, iheap, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( LINKEDLIST, ll, linked, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( LIST, l, list, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( MULTIMAP, mm, mmap, int, int) -CMC_COLLECTION_GENERATE_HEADER( MULTISET, ms, mset, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( QUEUE, q, queue, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( SORTEDLIST, sl, slist, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( STACK, s, stack, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( TREESET, ts, tset, /* K */, int) -CMC_COLLECTION_GENERATE_HEADER( TREEMAP, tm, tmap, int, int) diff --git a/tests/sep/main.c b/tests/sep/main.c deleted file mode 100644 index 350a863..0000000 --- a/tests/sep/main.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "collections.h" -#include - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -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, NULL, NULL); - struct hmap *hm = hm_new_custom(100, 0.6, NULL, NULL, NULL, NULL); - struct hset *hs = hs_new_custom(100, 0.6, NULL, NULL, NULL, NULL); - struct heap *h = h_new_custom(100, cmc_max_heap, NULL, NULL, NULL); - struct iheap *ih = ih_new_custom(100, NULL, NULL, NULL); - struct linked *ll = ll_new_custom(NULL, NULL); - struct list *l = l_new_custom(100, NULL, NULL); - struct mmap *mm = mm_new_custom(100, 0.8, NULL, NULL, NULL, NULL); - struct mset *ms = ms_new_custom(100, 0.6, NULL, NULL, NULL, NULL); - struct queue *q = q_new_custom(100, NULL, NULL); - struct slist *sl = sl_new_custom(100, NULL, NULL, NULL); - struct stack *s = s_new_custom(100, NULL, NULL); - struct tmap *tm = tm_new_custom(NULL, NULL, NULL); - struct tset *ts = ts_new_custom(NULL, NULL, NULL); - - printf("+--------------------------------------------------+\n"); - printf("| Separate Header and Source is Working |\n"); - printf("+--------------------------------------------------+\n"); - - bm_free(bm); - d_free(d, NULL); - hm_free(hm, NULL); - hs_free(hs, NULL); - h_free(h, NULL); - ih_free(ih, NULL); - ll_free(ll, NULL); - l_free(l, NULL); - mm_free(mm, NULL); - ms_free(ms, NULL); - q_free(q, NULL); - sl_free(sl, NULL); - s_free(s, NULL); - tm_free(tm, NULL); - ts_free(ts, NULL); - - return 0; -} diff --git a/tests/main/src/bitset.c b/tests/src/cmc/bitset.c similarity index 83% rename from tests/main/src/bitset.c rename to tests/src/cmc/bitset.c index 6fc38ba..68baf71 100644 --- a/tests/main/src/bitset.c +++ b/tests/src/cmc/bitset.c @@ -1,51 +1,6 @@ -#ifndef CMC_TEST_SRC_BITSET -#define CMC_TEST_SRC_BITSET #include "cmc/bitset.h" -struct bitset -{ - cmc_bitset_word *buffer; - size_t capacity; - int flag; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct bitset_iter -{ - struct bitset *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct bitset *bs_new(size_t n_bits); -struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -struct bitset bs_init(size_t n_bits); -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void bs_free(struct bitset *_bitset_); -void bs_release(struct bitset _bitset_); -void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool bs_set(struct bitset *_bitset_, size_t bit_index); -_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_clear(struct bitset *_bitset_, size_t bit_index); -_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_flip(struct bitset *_bitset_, size_t bit_index); -_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state); -_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state); -_Bool bs_set_all(struct bitset *_bitset_); -_Bool bs_clear_all(struct bitset *_bitset_); -_Bool bs_flip_all(struct bitset *_bitset_); -_Bool bs_get(struct bitset *_bitset_, size_t bit_index); -_Bool bs_resize(struct bitset *_bitset_, size_t n_bits); -static inline size_t bs_bit_to_index(size_t idx) -{ - static const size_t shift = - ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 - ? 6 - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; - return idx >> shift; -} _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize); struct bitset *bs_new(size_t n_bits) { @@ -53,6 +8,7 @@ struct bitset *bs_new(size_t n_bits) } struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) { + ; if (n_bits < 1) return ((void *)0); if (!alloc) @@ -336,5 +292,3 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) _bitset_->flag = CMC_FLAG_OK; return 1; } - -#endif /* CMC_TEST_SRC_BITSET */ diff --git a/tests/main/src/deque.c b/tests/src/cmc/deque.c similarity index 83% rename from tests/main/src/deque.c rename to tests/src/cmc/deque.c index dc5f600..ede6e29 100644 --- a/tests/main/src/deque.c +++ b/tests/src/cmc/deque.c @@ -1,78 +1,6 @@ -#ifndef CMC_TEST_SRC_DEQUE -#define CMC_TEST_SRC_DEQUE #include "cmc/deque.h" -struct deque -{ - size_t *buffer; - size_t capacity; - size_t count; - size_t front; - size_t back; - int flag; - struct deque_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct deque_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct deque *d_new(size_t capacity, struct deque_fval *f_val); -struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void d_clear(struct deque *_deque_); -void d_free(struct deque *_deque_); -void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool d_push_front(struct deque *_deque_, size_t value); -_Bool d_push_back(struct deque *_deque_, size_t value); -_Bool d_pop_front(struct deque *_deque_); -_Bool d_pop_back(struct deque *_deque_); -size_t d_front(struct deque *_deque_); -size_t d_back(struct deque *_deque_); -_Bool d_contains(struct deque *_deque_, size_t value); -_Bool d_empty(struct deque *_deque_); -_Bool d_full(struct deque *_deque_); -size_t d_count(struct deque *_deque_); -size_t d_capacity(struct deque *_deque_); -int d_flag(struct deque *_deque_); -_Bool d_resize(struct deque *_deque_, size_t capacity); -struct deque *d_copy_of(struct deque *_deque_); -_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_); -struct deque d_init(size_t capacity, struct deque_fval *f_val); -struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void d_release(struct deque _deque_); -struct deque_iter -{ - struct deque *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct deque_iter d_iter_start(struct deque *target); -struct deque_iter d_iter_end(struct deque *target); -_Bool d_iter_at_start(struct deque_iter *iter); -_Bool d_iter_at_end(struct deque_iter *iter); -_Bool d_iter_to_start(struct deque_iter *iter); -_Bool d_iter_to_end(struct deque_iter *iter); -_Bool d_iter_next(struct deque_iter *iter); -_Bool d_iter_prev(struct deque_iter *iter); -_Bool d_iter_advance(struct deque_iter *iter, size_t steps); -_Bool d_iter_rewind(struct deque_iter *iter, size_t steps); -_Bool d_iter_go_to(struct deque_iter *iter, size_t index); -size_t d_iter_value(struct deque_iter *iter); -size_t *d_iter_rvalue(struct deque_iter *iter); -size_t d_iter_index(struct deque_iter *iter); -_Bool d_to_string(struct deque *_deque_, FILE *fptr); -_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end); struct deque *d_new(size_t capacity, struct deque_fval *f_val) { return d_new_custom(capacity, f_val, ((void *)0), ((void *)0)); @@ -586,5 +514,3 @@ _Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char * fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_DEQUE */ diff --git a/tests/main/src/hashbidimap.c b/tests/src/cmc/hashbidimap.c similarity index 86% rename from tests/main/src/hashbidimap.c rename to tests/src/cmc/hashbidimap.c index 42e2c8d..c7a1b70 100644 --- a/tests/main/src/hashbidimap.c +++ b/tests/src/cmc/hashbidimap.c @@ -1,101 +1,6 @@ -#ifndef CMC_TEST_SRC_HASHBIDIMAP -#define CMC_TEST_SRC_HASHBIDIMAP #include "cmc/hashbidimap.h" -struct hashbidimap -{ - struct hashbidimap_entry *(*buffer)[2]; - size_t capacity; - size_t count; - double load; - int flag; - struct hashbidimap_fkey *f_key; - struct hashbidimap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; - struct hashbidimap_iter (*it_start)(struct hashbidimap *); - struct hashbidimap_iter (*it_end)(struct hashbidimap *); -}; -struct hashbidimap_entry -{ - size_t key; - size_t value; - size_t dist[2]; - struct hashbidimap_entry **ref[2]; -}; -struct hashbidimap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashbidimap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashbidimap_iter -{ - struct hashbidimap *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val); -struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hbm_clear(struct hashbidimap *_map_); -void hbm_free(struct hashbidimap *_map_); -void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value); -_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key); -_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val); -_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val); -_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val); -size_t hbm_get_key(struct hashbidimap *_map_, size_t val); -size_t hbm_get_val(struct hashbidimap *_map_, size_t key); -_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key); -_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val); -_Bool hbm_empty(struct hashbidimap *_map_); -_Bool hbm_full(struct hashbidimap *_map_); -size_t hbm_count(struct hashbidimap *_map_); -size_t hbm_capacity(struct hashbidimap *_map_); -double hbm_load(struct hashbidimap *_map_); -int hbm_flag(struct hashbidimap *_map_); -_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity); -struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_); -_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_); -struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target); -void hbm_iter_free(struct hashbidimap_iter *iter); -void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target); -_Bool hbm_iter_start(struct hashbidimap_iter *iter); -_Bool hbm_iter_end(struct hashbidimap_iter *iter); -void hbm_iter_to_start(struct hashbidimap_iter *iter); -void hbm_iter_to_end(struct hashbidimap_iter *iter); -_Bool hbm_iter_next(struct hashbidimap_iter *iter); -_Bool hbm_iter_prev(struct hashbidimap_iter *iter); -_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps); -_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps); -_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); -size_t hbm_iter_key(struct hashbidimap_iter *iter); -size_t hbm_iter_value(struct hashbidimap_iter *iter); -size_t hbm_iter_index(struct hashbidimap_iter *iter); -_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr); -_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value); static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key); static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val); @@ -949,5 +854,3 @@ _Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_HASHBIDIMAP */ diff --git a/tests/main/src/hashmap.c b/tests/src/cmc/hashmap.c similarity index 85% rename from tests/main/src/hashmap.c rename to tests/src/cmc/hashmap.c index 37980ab..8d49630 100644 --- a/tests/main/src/hashmap.c +++ b/tests/src/cmc/hashmap.c @@ -1,100 +1,6 @@ -#ifndef CMC_TEST_SRC_HASHMAP -#define CMC_TEST_SRC_HASHMAP #include "cmc/hashmap.h" -struct hashmap -{ - struct hashmap_entry *buffer; - size_t capacity; - size_t count; - double load; - int flag; - struct hashmap_fkey *f_key; - struct hashmap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmap_entry -{ - size_t key; - size_t value; - size_t dist; - enum cmc_entry_state state; -}; -struct hashmap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); -struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hm_clear(struct hashmap *_map_); -void hm_free(struct hashmap *_map_); -void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); -_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value); -_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value); -_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value); -_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value); -size_t hm_get(struct hashmap *_map_, size_t key); -size_t *hm_get_ref(struct hashmap *_map_, size_t key); -_Bool hm_contains(struct hashmap *_map_, size_t key); -_Bool hm_empty(struct hashmap *_map_); -_Bool hm_full(struct hashmap *_map_); -size_t hm_count(struct hashmap *_map_); -size_t hm_capacity(struct hashmap *_map_); -double hm_load(struct hashmap *_map_); -int hm_flag(struct hashmap *_map_); -_Bool hm_resize(struct hashmap *_map_, size_t capacity); -struct hashmap *hm_copy_of(struct hashmap *_map_); -_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_); -struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); -struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hm_release(struct hashmap _map_); -struct hashmap_iter -{ - struct hashmap *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmap_iter hm_iter_start(struct hashmap *target); -struct hashmap_iter hm_iter_end(struct hashmap *target); -_Bool hm_iter_at_start(struct hashmap_iter *iter); -_Bool hm_iter_at_end(struct hashmap_iter *iter); -_Bool hm_iter_to_start(struct hashmap_iter *iter); -_Bool hm_iter_to_end(struct hashmap_iter *iter); -_Bool hm_iter_next(struct hashmap_iter *iter); -_Bool hm_iter_prev(struct hashmap_iter *iter); -_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps); -_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps); -_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index); -size_t hm_iter_key(struct hashmap_iter *iter); -size_t hm_iter_value(struct hashmap_iter *iter); -size_t *hm_iter_rvalue(struct hashmap_iter *iter); -size_t hm_iter_index(struct hashmap_iter *iter); -_Bool hm_to_string(struct hashmap *_map_, FILE *fptr); -_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key); static size_t hm_impl_calculate_size(size_t required); struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) @@ -884,5 +790,3 @@ _Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_HASHMAP */ diff --git a/tests/main/src/hashmultimap.c b/tests/src/cmc/hashmultimap.c similarity index 86% rename from tests/main/src/hashmultimap.c rename to tests/src/cmc/hashmultimap.c index 0813264..7450bee 100644 --- a/tests/main/src/hashmultimap.c +++ b/tests/src/cmc/hashmultimap.c @@ -1,102 +1,6 @@ -#ifndef CMC_TEST_SRC_HASHMULTIMAP -#define CMC_TEST_SRC_HASHMULTIMAP #include "cmc/hashmultimap.h" -struct hashmultimap -{ - struct hashmultimap_entry *(*buffer)[2]; - size_t capacity; - size_t count; - double load; - int flag; - struct hashmultimap_fkey *f_key; - struct hashmultimap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmultimap_entry -{ - size_t key; - size_t value; - struct hashmultimap_entry *next; - struct hashmultimap_entry *prev; -}; -struct hashmultimap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultimap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val); -struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hmm_clear(struct hashmultimap *_map_); -void hmm_free(struct hashmultimap *_map_); -void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value); -_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value); -size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values); -_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value); -size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values); -_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value); -_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value); -size_t hmm_get(struct hashmultimap *_map_, size_t key); -size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key); -_Bool hmm_contains(struct hashmultimap *_map_, size_t key); -_Bool hmm_empty(struct hashmultimap *_map_); -_Bool hmm_full(struct hashmultimap *_map_); -size_t hmm_count(struct hashmultimap *_map_); -size_t hmm_key_count(struct hashmultimap *_map_, size_t key); -size_t hmm_capacity(struct hashmultimap *_map_); -double hmm_load(struct hashmultimap *_map_); -int hmm_flag(struct hashmultimap *_map_); -_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity); -struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_); -_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_); -struct hashmultimap_iter -{ - struct hashmultimap *target; - struct hashmultimap_entry *curr_entry; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target); -struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target); -_Bool hmm_iter_at_start(struct hashmultimap_iter *iter); -_Bool hmm_iter_at_end(struct hashmultimap_iter *iter); -_Bool hmm_iter_to_start(struct hashmultimap_iter *iter); -_Bool hmm_iter_to_end(struct hashmultimap_iter *iter); -_Bool hmm_iter_next(struct hashmultimap_iter *iter); -_Bool hmm_iter_prev(struct hashmultimap_iter *iter); -_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps); -_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps); -_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index); -size_t hmm_iter_key(struct hashmultimap_iter *iter); -size_t hmm_iter_value(struct hashmultimap_iter *iter); -size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter); -size_t hmm_iter_index(struct hashmultimap_iter *iter); -_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr); -_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value); struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key); size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key); @@ -1005,5 +909,3 @@ _Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_HASHMULTIMAP */ diff --git a/tests/main/src/hashmultiset.c b/tests/src/cmc/hashmultiset.c similarity index 86% rename from tests/main/src/hashmultiset.c rename to tests/src/cmc/hashmultiset.c index ff0c2a7..e348d67 100644 --- a/tests/main/src/hashmultiset.c +++ b/tests/src/cmc/hashmultiset.c @@ -1,98 +1,6 @@ -#ifndef CMC_TEST_SRC_HASHMULTISET -#define CMC_TEST_SRC_HASHMULTISET #include "cmc/hashmultiset.h" -struct hashmultiset -{ - struct hashmultiset_entry *buffer; - size_t capacity; - size_t count; - size_t cardinality; - double load; - int flag; - struct hashmultiset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmultiset_entry -{ - size_t value; - size_t multiplicity; - size_t dist; - enum cmc_entry_state state; -}; -struct hashmultiset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val); -struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hms_clear(struct hashmultiset *_set_); -void hms_free(struct hashmultiset *_set_); -void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hms_insert(struct hashmultiset *_set_, size_t value); -_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count); -_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity); -_Bool hms_remove(struct hashmultiset *_set_, size_t value); -size_t hms_remove_all(struct hashmultiset *_set_, size_t value); -_Bool hms_max(struct hashmultiset *_set_, size_t *value); -_Bool hms_min(struct hashmultiset *_set_, size_t *value); -size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value); -_Bool hms_contains(struct hashmultiset *_set_, size_t value); -_Bool hms_empty(struct hashmultiset *_set_); -_Bool hms_full(struct hashmultiset *_set_); -size_t hms_count(struct hashmultiset *_set_); -size_t hms_cardinality(struct hashmultiset *_set_); -size_t hms_capacity(struct hashmultiset *_set_); -double hms_load(struct hashmultiset *_set_); -int hms_flag(struct hashmultiset *_set_); -_Bool hms_resize(struct hashmultiset *_set_, size_t capacity); -struct hashmultiset *hms_copy_of(struct hashmultiset *_set_); -_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset_iter -{ - struct hashmultiset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmultiset_iter hms_iter_start(struct hashmultiset *target); -struct hashmultiset_iter hms_iter_end(struct hashmultiset *target); -_Bool hms_iter_at_start(struct hashmultiset_iter *iter); -_Bool hms_iter_at_end(struct hashmultiset_iter *iter); -_Bool hms_iter_to_start(struct hashmultiset_iter *iter); -_Bool hms_iter_to_end(struct hashmultiset_iter *iter); -_Bool hms_iter_next(struct hashmultiset_iter *iter); -_Bool hms_iter_prev(struct hashmultiset_iter *iter); -_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps); -_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps); -_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index); -size_t hms_iter_value(struct hashmultiset_iter *iter); -size_t hms_iter_multiplicity(struct hashmultiset_iter *iter); -size_t hms_iter_index(struct hashmultiset_iter *iter); -struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr); -_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value); static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node); static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value); @@ -1036,5 +944,3 @@ _Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_HASHMULTISET */ diff --git a/tests/main/src/hashset.c b/tests/src/cmc/hashset.c similarity index 86% rename from tests/main/src/hashset.c rename to tests/src/cmc/hashset.c index cf11adb..de158d7 100644 --- a/tests/main/src/hashset.c +++ b/tests/src/cmc/hashset.c @@ -1,88 +1,6 @@ -#ifndef CMC_TEST_SRC_HASHSET -#define CMC_TEST_SRC_HASHSET #include "cmc/hashset.h" -struct hashset -{ - struct hashset_entry *buffer; - size_t capacity; - size_t count; - double load; - int flag; - struct hashset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashset_entry -{ - size_t value; - size_t dist; - enum cmc_entry_state state; -}; -struct hashset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val); -struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hs_clear(struct hashset *_set_); -void hs_free(struct hashset *_set_); -void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hs_insert(struct hashset *_set_, size_t value); -_Bool hs_remove(struct hashset *_set_, size_t value); -_Bool hs_max(struct hashset *_set_, size_t *value); -_Bool hs_min(struct hashset *_set_, size_t *value); -_Bool hs_contains(struct hashset *_set_, size_t value); -_Bool hs_empty(struct hashset *_set_); -_Bool hs_full(struct hashset *_set_); -size_t hs_count(struct hashset *_set_); -size_t hs_capacity(struct hashset *_set_); -double hs_load(struct hashset *_set_); -int hs_flag(struct hashset *_set_); -_Bool hs_resize(struct hashset *_set_, size_t capacity); -struct hashset *hs_copy_of(struct hashset *_set_); -_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_); -struct hashset_iter -{ - struct hashset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashset_iter hs_iter_start(struct hashset *target); -struct hashset_iter hs_iter_end(struct hashset *target); -_Bool hs_iter_at_start(struct hashset_iter *iter); -_Bool hs_iter_at_end(struct hashset_iter *iter); -_Bool hs_iter_to_start(struct hashset_iter *iter); -_Bool hs_iter_to_end(struct hashset_iter *iter); -_Bool hs_iter_next(struct hashset_iter *iter); -_Bool hs_iter_prev(struct hashset_iter *iter); -_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps); -_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps); -_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index); -size_t hs_iter_value(struct hashset_iter *iter); -size_t hs_iter_index(struct hashset_iter *iter); -struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_to_string(struct hashset *_set_, FILE *fptr); -_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value); static size_t hs_impl_calculate_size(size_t required); struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val) @@ -835,5 +753,3 @@ _Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_HASHSET */ diff --git a/tests/main/src/heap.c b/tests/src/cmc/heap.c similarity index 82% rename from tests/main/src/heap.c rename to tests/src/cmc/heap.c index 5e435b9..11cd537 100644 --- a/tests/main/src/heap.c +++ b/tests/src/cmc/heap.c @@ -1,68 +1,6 @@ -#ifndef CMC_TEST_SRC_HEAP -#define CMC_TEST_SRC_HEAP #include "cmc/heap.h" -struct heap -{ - size_t *buffer; - size_t capacity; - size_t count; - enum cmc_heap_order HO; - int flag; - struct heap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct heap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val); -struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void h_clear(struct heap *_heap_); -void h_free(struct heap *_heap_); -void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool h_insert(struct heap *_heap_, size_t value); -_Bool h_remove(struct heap *_heap_); -size_t h_peek(struct heap *_heap_); -_Bool h_contains(struct heap *_heap_, size_t value); -_Bool h_empty(struct heap *_heap_); -_Bool h_full(struct heap *_heap_); -size_t h_count(struct heap *_heap_); -size_t h_capacity(struct heap *_heap_); -int h_flag(struct heap *_heap_); -_Bool h_resize(struct heap *_heap_, size_t capacity); -struct heap *h_copy_of(struct heap *_heap_); -_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_); -struct heap_iter -{ - struct heap *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct heap_iter h_iter_start(struct heap *target); -struct heap_iter h_iter_end(struct heap *target); -_Bool h_iter_at_start(struct heap_iter *iter); -_Bool h_iter_at_end(struct heap_iter *iter); -_Bool h_iter_to_start(struct heap_iter *iter); -_Bool h_iter_to_end(struct heap_iter *iter); -_Bool h_iter_next(struct heap_iter *iter); -_Bool h_iter_prev(struct heap_iter *iter); -_Bool h_iter_advance(struct heap_iter *iter, size_t steps); -_Bool h_iter_rewind(struct heap_iter *iter, size_t steps); -_Bool h_iter_go_to(struct heap_iter *iter, size_t index); -size_t h_iter_value(struct heap_iter *iter); -size_t h_iter_index(struct heap_iter *iter); -_Bool h_to_string(struct heap *_heap_, FILE *fptr); -_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); static void h_impl_float_up(struct heap *_heap_, size_t index); static void h_impl_float_down(struct heap *_heap_, size_t index); struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val) @@ -484,5 +422,3 @@ _Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *se fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_HEAP */ diff --git a/tests/main/src/intervalheap.c b/tests/src/cmc/intervalheap.c similarity index 86% rename from tests/main/src/intervalheap.c rename to tests/src/cmc/intervalheap.c index b609bfb..56ac313 100644 --- a/tests/main/src/intervalheap.c +++ b/tests/src/cmc/intervalheap.c @@ -1,72 +1,6 @@ -#ifndef CMC_TEST_SRC_INTERVALHEAP -#define CMC_TEST_SRC_INTERVALHEAP #include "cmc/intervalheap.h" -struct intervalheap -{ - size_t (*buffer)[2]; - size_t capacity; - size_t size; - size_t count; - int flag; - struct intervalheap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct intervalheap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val); -struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ih_clear(struct intervalheap *_heap_); -void ih_free(struct intervalheap *_heap_); -void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ih_insert(struct intervalheap *_heap_, size_t value); -_Bool ih_remove_max(struct intervalheap *_heap_); -_Bool ih_remove_min(struct intervalheap *_heap_); -_Bool ih_update_max(struct intervalheap *_heap_, size_t value); -_Bool ih_update_min(struct intervalheap *_heap_, size_t value); -size_t ih_max(struct intervalheap *_heap_); -size_t ih_min(struct intervalheap *_heap_); -_Bool ih_contains(struct intervalheap *_heap_, size_t value); -_Bool ih_empty(struct intervalheap *_heap_); -_Bool ih_full(struct intervalheap *_heap_); -size_t ih_count(struct intervalheap *_heap_); -size_t ih_capacity(struct intervalheap *_heap_); -int ih_flag(struct intervalheap *_heap_); -_Bool ih_resize(struct intervalheap *_heap_, size_t capacity); -struct intervalheap *ih_copy_of(struct intervalheap *_heap_); -_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_); -struct intervalheap_iter -{ - struct intervalheap *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct intervalheap_iter ih_iter_start(struct intervalheap *target); -struct intervalheap_iter ih_iter_end(struct intervalheap *target); -_Bool ih_iter_at_start(struct intervalheap_iter *iter); -_Bool ih_iter_at_end(struct intervalheap_iter *iter); -_Bool ih_iter_to_start(struct intervalheap_iter *iter); -_Bool ih_iter_to_end(struct intervalheap_iter *iter); -_Bool ih_iter_next(struct intervalheap_iter *iter); -_Bool ih_iter_prev(struct intervalheap_iter *iter); -_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps); -_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps); -_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index); -size_t ih_iter_value(struct intervalheap_iter *iter); -size_t ih_iter_index(struct intervalheap_iter *iter); -_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr); -_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); static void ih_impl_float_up_max(struct intervalheap *_heap_); static void ih_impl_float_up_min(struct intervalheap *_heap_); static void ih_impl_float_down_max(struct intervalheap *_heap_); @@ -750,5 +684,3 @@ _Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_INTERVALHEAP */ diff --git a/tests/main/src/linkedlist.c b/tests/src/cmc/linkedlist.c similarity index 81% rename from tests/main/src/linkedlist.c rename to tests/src/cmc/linkedlist.c index 3030f9b..32dbae8 100644 --- a/tests/main/src/linkedlist.c +++ b/tests/src/cmc/linkedlist.c @@ -1,92 +1,6 @@ -#ifndef CMC_TEST_SRC_LINKEDLIST -#define CMC_TEST_SRC_LINKEDLIST #include "cmc/linkedlist.h" -struct linkedlist -{ - struct linkedlist_node *head; - struct linkedlist_node *tail; - size_t count; - int flag; - struct linkedlist_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct linkedlist_node -{ - size_t value; - struct linkedlist_node *next; - struct linkedlist_node *prev; -}; -struct linkedlist_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct linkedlist *ll_new(struct linkedlist_fval *f_val); -struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ll_clear(struct linkedlist *_list_); -void ll_free(struct linkedlist *_list_); -void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ll_push_front(struct linkedlist *_list_, size_t value); -_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index); -_Bool ll_push_back(struct linkedlist *_list_, size_t value); -_Bool ll_pop_front(struct linkedlist *_list_); -_Bool ll_pop_at(struct linkedlist *_list_, size_t index); -_Bool ll_pop_back(struct linkedlist *_list_); -size_t ll_front(struct linkedlist *_list_); -size_t ll_get(struct linkedlist *_list_, size_t index); -size_t *ll_get_ref(struct linkedlist *_list_, size_t index); -size_t ll_back(struct linkedlist *_list_); -_Bool ll_contains(struct linkedlist *_list_, size_t value); -_Bool ll_empty(struct linkedlist *_list_); -size_t ll_count(struct linkedlist *_list_); -int ll_flag(struct linkedlist *_list_); -struct linkedlist *ll_copy_of(struct linkedlist *_list_); -_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_); -struct linkedlist_iter -{ - struct linkedlist *target; - struct linkedlist_node *cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct linkedlist_iter ll_iter_start(struct linkedlist *target); -struct linkedlist_iter ll_iter_end(struct linkedlist *target); -_Bool ll_iter_at_start(struct linkedlist_iter *iter); -_Bool ll_iter_at_end(struct linkedlist_iter *iter); -_Bool ll_iter_to_start(struct linkedlist_iter *iter); -_Bool ll_iter_to_end(struct linkedlist_iter *iter); -_Bool ll_iter_next(struct linkedlist_iter *iter); -_Bool ll_iter_prev(struct linkedlist_iter *iter); -_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps); -_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps); -_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index); -size_t ll_iter_value(struct linkedlist_iter *iter); -size_t *ll_iter_rvalue(struct linkedlist_iter *iter); -size_t ll_iter_index(struct linkedlist_iter *iter); -struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter); -struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); -void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_head(struct linkedlist *_list_); -struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); -struct linkedlist_node *ll_tail(struct linkedlist *_list_); -_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); -struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); -_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr); -_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); struct linkedlist *ll_new(struct linkedlist_fval *f_val) { return ll_new_custom(f_val, ((void *)0), ((void *)0)); @@ -767,5 +681,3 @@ _Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const c fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_LINKEDLIST */ diff --git a/tests/main/src/list.c b/tests/src/cmc/list.c similarity index 84% rename from tests/main/src/list.c rename to tests/src/cmc/list.c index 5c5ffbf..6d65763 100644 --- a/tests/main/src/list.c +++ b/tests/src/cmc/list.c @@ -1,82 +1,6 @@ -#ifndef CMC_TEST_SRC_LIST -#define CMC_TEST_SRC_LIST #include "cmc/list.h" -struct list -{ - size_t *buffer; - size_t capacity; - size_t count; - int flag; - struct list_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct list_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct list *l_new(size_t capacity, struct list_fval *f_val); -struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void l_clear(struct list *_list_); -void l_free(struct list *_list_); -void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool l_push_front(struct list *_list_, size_t value); -_Bool l_push_at(struct list *_list_, size_t value, size_t index); -_Bool l_push_back(struct list *_list_, size_t value); -_Bool l_pop_front(struct list *_list_); -_Bool l_pop_at(struct list *_list_, size_t index); -_Bool l_pop_back(struct list *_list_); -size_t l_front(struct list *_list_); -size_t l_get(struct list *_list_, size_t index); -size_t *l_get_ref(struct list *_list_, size_t index); -size_t l_back(struct list *_list_); -size_t l_index_of(struct list *_list_, size_t value, _Bool from_start); -_Bool l_contains(struct list *_list_, size_t value); -_Bool l_empty(struct list *_list_); -_Bool l_full(struct list *_list_); -size_t l_count(struct list *_list_); -_Bool l_fits(struct list *_list_, size_t size); -size_t l_capacity(struct list *_list_); -int l_flag(struct list *_list_); -_Bool l_resize(struct list *_list_, size_t capacity); -struct list *l_copy_of(struct list *_list_); -_Bool l_equals(struct list *_list1_, struct list *_list2_); -struct list_iter -{ - struct list *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct list_iter l_iter_start(struct list *target); -struct list_iter l_iter_end(struct list *target); -_Bool l_iter_at_start(struct list_iter *iter); -_Bool l_iter_at_end(struct list_iter *iter); -_Bool l_iter_to_start(struct list_iter *iter); -_Bool l_iter_to_end(struct list_iter *iter); -_Bool l_iter_next(struct list_iter *iter); -_Bool l_iter_prev(struct list_iter *iter); -_Bool l_iter_advance(struct list_iter *iter, size_t steps); -_Bool l_iter_rewind(struct list_iter *iter, size_t steps); -_Bool l_iter_go_to(struct list_iter *iter, size_t index); -size_t l_iter_value(struct list_iter *iter); -size_t *l_iter_rvalue(struct list_iter *iter); -size_t l_iter_index(struct list_iter *iter); -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); -_Bool l_to_string(struct list *_list_, FILE *fptr); -_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end); struct list *l_new(size_t capacity, struct list_fval *f_val) { return l_new_custom(capacity, f_val, ((void *)0), ((void *)0)); @@ -717,5 +641,3 @@ _Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *se fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_LIST */ diff --git a/tests/main/src/queue.c b/tests/src/cmc/queue.c similarity index 82% rename from tests/main/src/queue.c rename to tests/src/cmc/queue.c index e5e6d85..de55581 100644 --- a/tests/main/src/queue.c +++ b/tests/src/cmc/queue.c @@ -1,71 +1,6 @@ -#ifndef CMC_TEST_SRC_QUEUE -#define CMC_TEST_SRC_QUEUE #include "cmc/queue.h" -struct queue -{ - size_t *buffer; - size_t capacity; - size_t count; - size_t front; - size_t back; - int flag; - struct queue_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct queue_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct queue_iter -{ - struct queue *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct queue *q_new(size_t capacity, struct queue_fval *f_val); -struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void q_clear(struct queue *_queue_); -void q_free(struct queue *_queue_); -void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool q_enqueue(struct queue *_queue_, size_t value); -_Bool q_dequeue(struct queue *_queue_); -size_t q_peek(struct queue *_queue_); -_Bool q_contains(struct queue *_queue_, size_t value); -_Bool q_empty(struct queue *_queue_); -_Bool q_full(struct queue *_queue_); -size_t q_count(struct queue *_queue_); -size_t q_capacity(struct queue *_queue_); -int q_flag(struct queue *_queue_); -_Bool q_resize(struct queue *_queue_, size_t capacity); -struct queue *q_copy_of(struct queue *_queue_); -_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_); -struct queue_iter q_iter_start(struct queue *target); -struct queue_iter q_iter_end(struct queue *target); -_Bool q_iter_at_start(struct queue_iter *iter); -_Bool q_iter_at_end(struct queue_iter *iter); -_Bool q_iter_to_start(struct queue_iter *iter); -_Bool q_iter_to_end(struct queue_iter *iter); -_Bool q_iter_next(struct queue_iter *iter); -_Bool q_iter_prev(struct queue_iter *iter); -_Bool q_iter_advance(struct queue_iter *iter, size_t steps); -_Bool q_iter_rewind(struct queue_iter *iter, size_t steps); -_Bool q_iter_go_to(struct queue_iter *iter, size_t index); -size_t q_iter_value(struct queue_iter *iter); -size_t *q_iter_rvalue(struct queue_iter *iter); -size_t q_iter_index(struct queue_iter *iter); -_Bool q_to_string(struct queue *_queue_, FILE *fptr); -_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end); struct queue *q_new(size_t capacity, struct queue_fval *f_val) { return q_new_custom(capacity, f_val, ((void *)0), ((void *)0)); @@ -494,5 +429,3 @@ _Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char * fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_QUEUE */ diff --git a/tests/main/src/sortedlist.c b/tests/src/cmc/sortedlist.c similarity index 83% rename from tests/main/src/sortedlist.c rename to tests/src/cmc/sortedlist.c index 480a08c..d130322 100644 --- a/tests/main/src/sortedlist.c +++ b/tests/src/cmc/sortedlist.c @@ -1,72 +1,6 @@ -#ifndef CMC_TEST_SRC_SORTEDLIST -#define CMC_TEST_SRC_SORTEDLIST #include "cmc/sortedlist.h" -struct sortedlist -{ - size_t *buffer; - size_t capacity; - size_t count; - _Bool is_sorted; - int flag; - struct sortedlist_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct sortedlist_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val); -struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void sl_clear(struct sortedlist *_list_); -void sl_free(struct sortedlist *_list_); -void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool sl_insert(struct sortedlist *_list_, size_t value); -_Bool sl_remove(struct sortedlist *_list_, size_t index); -size_t sl_max(struct sortedlist *_list_); -size_t sl_min(struct sortedlist *_list_); -size_t sl_get(struct sortedlist *_list_, size_t index); -size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start); -_Bool sl_contains(struct sortedlist *_list_, size_t value); -_Bool sl_empty(struct sortedlist *_list_); -_Bool sl_full(struct sortedlist *_list_); -size_t sl_count(struct sortedlist *_list_); -size_t sl_capacity(struct sortedlist *_list_); -int sl_flag(struct sortedlist *_list_); -_Bool sl_resize(struct sortedlist *_list_, size_t capacity); -void sl_sort(struct sortedlist *_list_); -struct sortedlist *sl_copy_of(struct sortedlist *_list_); -_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_); -struct sortedlist_iter -{ - struct sortedlist *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct sortedlist_iter sl_iter_start(struct sortedlist *target); -struct sortedlist_iter sl_iter_end(struct sortedlist *target); -_Bool sl_iter_at_start(struct sortedlist_iter *iter); -_Bool sl_iter_at_end(struct sortedlist_iter *iter); -_Bool sl_iter_to_start(struct sortedlist_iter *iter); -_Bool sl_iter_to_end(struct sortedlist_iter *iter); -_Bool sl_iter_next(struct sortedlist_iter *iter); -_Bool sl_iter_prev(struct sortedlist_iter *iter); -_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps); -_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps); -_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index); -size_t sl_iter_value(struct sortedlist_iter *iter); -size_t sl_iter_index(struct sortedlist_iter *iter); -_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr); -_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value); static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value); void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); @@ -576,5 +510,3 @@ _Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const c fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_SORTEDLIST */ diff --git a/tests/main/src/stack.c b/tests/src/cmc/stack.c similarity index 79% rename from tests/main/src/stack.c rename to tests/src/cmc/stack.c index 1be2b1a..46cf798 100644 --- a/tests/main/src/stack.c +++ b/tests/src/cmc/stack.c @@ -1,68 +1,6 @@ -#ifndef CMC_TEST_SRC_STACK -#define CMC_TEST_SRC_STACK #include "cmc/stack.h" -struct stack -{ - size_t *buffer; - size_t capacity; - size_t count; - int flag; - struct stack_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct stack_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct stack *s_new(size_t capacity, struct stack_fval *f_val); -struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void s_clear(struct stack *_stack_); -void s_free(struct stack *_stack_); -void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool s_push(struct stack *_stack_, size_t value); -_Bool s_pop(struct stack *_stack_); -size_t s_top(struct stack *_stack_); -_Bool s_contains(struct stack *_stack_, size_t value); -_Bool s_empty(struct stack *_stack_); -_Bool s_full(struct stack *_stack_); -size_t s_count(struct stack *_stack_); -size_t s_capacity(struct stack *_stack_); -int s_flag(struct stack *_stack_); -_Bool s_resize(struct stack *_stack_, size_t capacity); -struct stack *s_copy_of(struct stack *_stack_); -_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_); -struct stack_iter -{ - struct stack *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct stack_iter s_iter_start(struct stack *target); -struct stack_iter s_iter_end(struct stack *target); -_Bool s_iter_at_start(struct stack_iter *iter); -_Bool s_iter_at_end(struct stack_iter *iter); -_Bool s_iter_to_start(struct stack_iter *iter); -_Bool s_iter_to_end(struct stack_iter *iter); -_Bool s_iter_next(struct stack_iter *iter); -_Bool s_iter_prev(struct stack_iter *iter); -_Bool s_iter_advance(struct stack_iter *iter, size_t steps); -_Bool s_iter_rewind(struct stack_iter *iter, size_t steps); -_Bool s_iter_go_to(struct stack_iter *iter, size_t index); -size_t s_iter_value(struct stack_iter *iter); -size_t *s_iter_rvalue(struct stack_iter *iter); -size_t s_iter_index(struct stack_iter *iter); -_Bool s_to_string(struct stack *_stack_, FILE *fptr); -_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end); struct stack *s_new(size_t capacity, struct stack_fval *f_val) { return s_new_custom(capacity, f_val, ((void *)0), ((void *)0)); @@ -235,7 +173,7 @@ struct stack *s_copy_of(struct stack *_stack_) _stack_->flag = CMC_FLAG_ERROR; return ((void *)0); } - (_stack_)->callbacks = callbacks; + (result)->callbacks = _stack_->callbacks; if (_stack_->f_val->cpy) { for (size_t i = 0; i < _stack_->count; i++) @@ -427,5 +365,3 @@ _Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char * fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_STACK */ diff --git a/tests/main/src/treemap.c b/tests/src/cmc/treemap.c similarity index 87% rename from tests/main/src/treemap.c rename to tests/src/cmc/treemap.c index fa081be..39ceb86 100644 --- a/tests/main/src/treemap.c +++ b/tests/src/cmc/treemap.c @@ -1,92 +1,6 @@ -#ifndef CMC_TEST_SRC_TREEMAP -#define CMC_TEST_SRC_TREEMAP #include "cmc/treemap.h" -struct treemap -{ - struct treemap_node *root; - size_t count; - int flag; - struct treemap_fkey *f_key; - struct treemap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct treemap_node -{ - size_t key; - size_t value; - unsigned char height; - struct treemap_node *right; - struct treemap_node *left; - struct treemap_node *parent; -}; -struct treemap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treemap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val); -struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void tm_clear(struct treemap *_map_); -void tm_free(struct treemap *_map_); -void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool tm_insert(struct treemap *_map_, size_t key, size_t value); -_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value); -_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value); -_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value); -_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value); -size_t tm_get(struct treemap *_map_, size_t key); -size_t *tm_get_ref(struct treemap *_map_, size_t key); -_Bool tm_contains(struct treemap *_map_, size_t key); -_Bool tm_empty(struct treemap *_map_); -size_t tm_count(struct treemap *_map_); -int tm_flag(struct treemap *_map_); -struct treemap *tm_copy_of(struct treemap *_map_); -_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_); -struct treemap_iter -{ - struct treemap *target; - struct treemap_node *cursor; - struct treemap_node *first; - struct treemap_node *last; - size_t index; - _Bool start; - _Bool end; -}; -struct treemap_iter tm_iter_start(struct treemap *target); -struct treemap_iter tm_iter_end(struct treemap *target); -_Bool tm_iter_at_start(struct treemap_iter *iter); -_Bool tm_iter_at_end(struct treemap_iter *iter); -_Bool tm_iter_to_start(struct treemap_iter *iter); -_Bool tm_iter_to_end(struct treemap_iter *iter); -_Bool tm_iter_next(struct treemap_iter *iter); -_Bool tm_iter_prev(struct treemap_iter *iter); -_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps); -_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps); -_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index); -size_t tm_iter_key(struct treemap_iter *iter); -size_t tm_iter_value(struct treemap_iter *iter); -size_t *tm_iter_rvalue(struct treemap_iter *iter); -size_t tm_iter_index(struct treemap_iter *iter); -_Bool tm_to_string(struct treemap *_map_, FILE *fptr); -_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value); static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key); static unsigned char tm_impl_h(struct treemap_node *node); @@ -888,5 +802,3 @@ _Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_TREEMAP */ diff --git a/tests/main/src/treeset.c b/tests/src/cmc/treeset.c similarity index 88% rename from tests/main/src/treeset.c rename to tests/src/cmc/treeset.c index 1bf5884..795a020 100644 --- a/tests/main/src/treeset.c +++ b/tests/src/cmc/treeset.c @@ -1,84 +1,6 @@ -#ifndef CMC_TEST_SRC_TREESET -#define CMC_TEST_SRC_TREESET #include "cmc/treeset.h" -struct treeset -{ - struct treeset_node *root; - size_t count; - int flag; - struct treeset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct treeset_node -{ - size_t value; - unsigned char height; - struct treeset_node *right; - struct treeset_node *left; - struct treeset_node *parent; -}; -struct treeset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treeset_iter -{ - struct treeset *target; - struct treeset_node *cursor; - struct treeset_node *first; - struct treeset_node *last; - size_t index; - _Bool start; - _Bool end; -}; -struct treeset *ts_new(struct treeset_fval *f_val); -struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ts_clear(struct treeset *_set_); -void ts_free(struct treeset *_set_); -void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ts_insert(struct treeset *_set_, size_t value); -_Bool ts_remove(struct treeset *_set_, size_t value); -_Bool ts_max(struct treeset *_set_, size_t *value); -_Bool ts_min(struct treeset *_set_, size_t *value); -_Bool ts_contains(struct treeset *_set_, size_t value); -_Bool ts_empty(struct treeset *_set_); -size_t ts_count(struct treeset *_set_); -int ts_flag(struct treeset *_set_); -struct treeset *ts_copy_of(struct treeset *_set_); -_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); -struct treeset_iter ts_iter_start(struct treeset *target); -struct treeset_iter ts_iter_end(struct treeset *target); -_Bool ts_iter_at_start(struct treeset_iter *iter); -_Bool ts_iter_at_end(struct treeset_iter *iter); -_Bool ts_iter_to_start(struct treeset_iter *iter); -_Bool ts_iter_to_end(struct treeset_iter *iter); -_Bool ts_iter_next(struct treeset_iter *iter); -_Bool ts_iter_prev(struct treeset_iter *iter); -_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps); -_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); -_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); -size_t ts_iter_value(struct treeset_iter *iter); -size_t ts_iter_index(struct treeset_iter *iter); -_Bool ts_to_string(struct treeset *_set_, FILE *fptr); -_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value); static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value); static unsigned char ts_impl_h(struct treeset_node *node); @@ -917,5 +839,3 @@ _Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char fprintf(fptr, "%s", end); return 1; } - -#endif /* CMC_TEST_SRC_TREESET */ diff --git a/tests/main/unt/bitset.c b/tests/unt/cmc/bitset.h similarity index 91% rename from tests/main/unt/bitset.c rename to tests/unt/cmc/bitset.h index 3e6053f..41f490e 100644 --- a/tests/main/unt/bitset.c +++ b/tests/unt/cmc/bitset.h @@ -1,13 +1,14 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_ITSET_H +#define CMC_TESTS_UNT_CMC_ITSET_H -#include "../src/bitset.c" +#include "../utl.h" + +#include "cmc/bitset.h" struct cmc_alloc_node *bs_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; -CMC_CREATE_UNIT(BitSet, true, { +CMC_CREATE_UNIT(CMCBitSet, true, { const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; printf("%s", cmc_test_color(5)); @@ -20,7 +21,10 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_not_equals(ptr, NULL, bs); cmc_assert_not_equals(ptr, NULL, bs->buffer); cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs->capacity); - cmc_assert_equals(ptr, &cmc_alloc_node_default, bs->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs->alloc->free); cmc_assert_equals(ptr, NULL, bs->callbacks); bs_free(bs); @@ -62,7 +66,10 @@ CMC_CREATE_UNIT(BitSet, true, { cmc_assert_not_equals(ptr, NULL, bs.buffer); cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs.capacity); - cmc_assert_equals(ptr, &cmc_alloc_node_default, bs.alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs.alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs.alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs.alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs.alloc->free); cmc_assert_equals(ptr, NULL, bs.callbacks); bs_release(bs); @@ -114,7 +121,10 @@ CMC_CREATE_UNIT(BitSet, true, { bs->flag = CMC_FLAG_ERROR; bs_customize(bs, NULL, NULL); - cmc_assert_equals(ptr, &cmc_alloc_node_default, bs->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs->alloc->free); cmc_assert_equals(ptr, NULL, bs->callbacks); cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); @@ -419,7 +429,7 @@ CMC_CREATE_UNIT(BitSet, true, { }); }); -CMC_CREATE_UNIT(BitSetIter, true, { +CMC_CREATE_UNIT(CMCBitSetIter, true, { // const size_t word_bytes = sizeof(cmc_bitset_word); // const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; @@ -439,14 +449,16 @@ CMC_CREATE_UNIT(BitSetIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = BitSet() + BitSetIter(); + int result = CMCBitSet() + CMCBitSetIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | BitSet Suit : %-47s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCBitSet Suit : %-47s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_ITSET_H */ diff --git a/tests/main/unt/deque.c b/tests/unt/cmc/deque.h similarity index 90% rename from tests/main/unt/deque.c rename to tests/unt/cmc/deque.h index 0bdb052..af4fb8e 100644 --- a/tests/main/unt/deque.c +++ b/tests/unt/cmc/deque.h @@ -1,8 +1,9 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_EQUE_H +#define CMC_TESTS_UNT_CMC_EQUE_H -#include "../src/deque.c" +#include "../utl.h" + +#include "cmc/deque.h" struct deque_fval *d_fval = &(struct deque_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp @@ -15,7 +16,7 @@ struct deque_fval *d_fval_counter = &(struct deque_fval){ struct cmc_alloc_node *d_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; -CMC_CREATE_UNIT(Deque, true, { +CMC_CREATE_UNIT(CMCDeque, true, { CMC_CREATE_TEST(PFX##_new(), { struct deque *d = d_new(1000000, d_fval); @@ -27,7 +28,10 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(size_t, 0, d->back); cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag); cmc_assert_equals(ptr, d_fval, d->f_val); - cmc_assert_equals(ptr, &cmc_alloc_node_default, d->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, d->alloc->free); cmc_assert_equals(ptr, NULL, d->callbacks); d_free(d); @@ -68,74 +72,77 @@ CMC_CREATE_UNIT(Deque, true, { cmc_assert_equals(ptr, NULL, d); }); - // CMC_CREATE_TEST(PFX##_init(), { - // struct deque d = d_init(1000000, d_fval); + CMC_CREATE_TEST(PFX##_init(), { + struct deque d = d_init(1000000, d_fval); - // cmc_assert_not_equals(ptr, NULL, d.buffer); - // cmc_assert_equals(size_t, 1000000, d.capacity); - // cmc_assert_equals(size_t, 0, d.count); - // cmc_assert_equals(size_t, 0, d.front); - // cmc_assert_equals(size_t, 0, d.back); - // cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); - // cmc_assert_equals(ptr, d_fval, d.f_val); - // cmc_assert_equals(ptr, &cmc_alloc_node_default, d.alloc); - // cmc_assert_equals(ptr, NULL, d.callbacks); + cmc_assert_not_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 1000000, d.capacity); + cmc_assert_equals(size_t, 0, d.count); + cmc_assert_equals(size_t, 0, d.front); + cmc_assert_equals(size_t, 0, d.back); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); + cmc_assert_equals(ptr, d_fval, d.f_val); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d.alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d.alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d.alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, d.alloc->free); + cmc_assert_equals(ptr, NULL, d.callbacks); - // d_release(d); + d_release(d); - // d = d_init(0, d_fval); + d = d_init(0, d_fval); - // cmc_assert_equals(size_t, 0, d.capacity); - // cmc_assert_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); - // d = d_init(1000, NULL); + d = d_init(1000, NULL); - // cmc_assert_equals(size_t, 0, d.capacity); - // cmc_assert_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); - // d = d_init(UINT64_MAX, d_fval); + d = d_init(UINT64_MAX, d_fval); - // cmc_assert_equals(size_t, 0, d.capacity); - // cmc_assert_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); - // if (d.buffer) - // d_release(d); - // }); + if (d.buffer) + d_release(d); + }); - // CMC_CREATE_TEST(PFX##_init_custom(), { - // struct deque d = - // d_init_custom(1000000, d_fval, d_alloc_node, callbacks); + CMC_CREATE_TEST(PFX##_init_custom(), { + struct deque d = + d_init_custom(1000000, d_fval, d_alloc_node, callbacks); - // cmc_assert_not_equals(ptr, NULL, d.buffer); - // cmc_assert_equals(size_t, 1000000, d.capacity); - // cmc_assert_equals(size_t, 0, d.count); - // cmc_assert_equals(size_t, 0, d.front); - // cmc_assert_equals(size_t, 0, d.back); - // cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); - // cmc_assert_equals(ptr, d_fval, d.f_val); - // cmc_assert_equals(ptr, d_alloc_node, d.alloc); - // cmc_assert_equals(ptr, callbacks, d.callbacks); + cmc_assert_not_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 1000000, d.capacity); + cmc_assert_equals(size_t, 0, d.count); + cmc_assert_equals(size_t, 0, d.front); + cmc_assert_equals(size_t, 0, d.back); + cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); + cmc_assert_equals(ptr, d_fval, d.f_val); + cmc_assert_equals(ptr, d_alloc_node, d.alloc); + cmc_assert_equals(ptr, callbacks, d.callbacks); - // d_release(d); + d_release(d); - // d = d_init_custom(0, d_fval, d_alloc_node, callbacks); + d = d_init_custom(0, d_fval, d_alloc_node, callbacks); - // cmc_assert_equals(size_t, 0, d.capacity); - // cmc_assert_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); - // d = d_init_custom(1000, NULL, d_alloc_node, callbacks); + d = d_init_custom(1000, NULL, d_alloc_node, callbacks); - // cmc_assert_equals(size_t, 0, d.capacity); - // cmc_assert_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); - // d = d_init_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); + d = d_init_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); - // cmc_assert_equals(size_t, 0, d.capacity); - // cmc_assert_equals(ptr, NULL, d.buffer); + cmc_assert_equals(size_t, 0, d.capacity); + cmc_assert_equals(ptr, NULL, d.buffer); - // if (d.buffer) - // d_release(d); - // }); + if (d.buffer) + d_release(d); + }); CMC_CREATE_TEST(PFX##_clear(), { v_total_free = 0; @@ -222,36 +229,36 @@ CMC_CREATE_UNIT(Deque, true, { v_total_free = 0; }); - // CMC_CREATE_TEST(PFX##_release(), { - // v_total_free = 0; + CMC_CREATE_TEST(PFX##_release(), { + v_total_free = 0; - // struct deque d = d_init(100, d_fval_counter); + struct deque d = d_init(100, d_fval_counter); - // cmc_assert_not_equals(ptr, NULL, d.buffer); + cmc_assert_not_equals(ptr, NULL, d.buffer); - // for (size_t i = 1; i <= 1000; i++) - // { - // if (i % 2 == 0) - // d_push_front(&d, i); - // else - // d_push_back(&d, i); - // } + for (size_t i = 1; i <= 1000; i++) + { + if (i % 2 == 0) + d_push_front(&d, i); + else + d_push_back(&d, i); + } - // cmc_assert_equals(size_t, 1000, d_count(&d)); + cmc_assert_equals(size_t, 1000, d_count(&d)); - // size_t sum = 0; - // for (size_t i = d.front, j = 0; j < d.count; - // i = (i + 1) % d.capacity, j++) - // sum += d.buffer[i]; + size_t sum = 0; + for (size_t i = d.front, j = 0; j < d.count; + i = (i + 1) % d.capacity, j++) + sum += d.buffer[i]; - // cmc_assert_equals(size_t, 500500, sum); + cmc_assert_equals(size_t, 500500, sum); - // d_release(d); + d_release(d); - // cmc_assert_equals(size_t, 1000, v_total_free); + cmc_assert_equals(size_t, 1000, v_total_free); - // v_total_free = 0; - // }); + v_total_free = 0; + }); CMC_CREATE_TEST(PFX##_customize(), { struct deque *d = d_new(100, d_fval); @@ -268,7 +275,10 @@ CMC_CREATE_UNIT(Deque, true, { d->flag = CMC_FLAG_ERROR; d_customize(d, NULL, NULL); - cmc_assert_equals(ptr, &cmc_alloc_node_default, d->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, d->alloc->free); cmc_assert_equals(ptr, NULL, d->callbacks); cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); @@ -1253,7 +1263,7 @@ CMC_CREATE_UNIT(Deque, true, { }); }); -CMC_CREATE_UNIT(DequeIter, true, { +CMC_CREATE_UNIT(CMCDequeIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct deque *d = d_new(100, d_fval); @@ -1712,14 +1722,16 @@ CMC_CREATE_UNIT(DequeIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = Deque() + DequeIter(); + int result = CMCDeque() + CMCDequeIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | Deque Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCDeque Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_EQUE_H */ diff --git a/tests/main/unt/hashbidimap.c b/tests/unt/cmc/hashbidimap.h similarity index 96% rename from tests/main/unt/hashbidimap.c rename to tests/unt/cmc/hashbidimap.h index 1d8bd1e..9c6c411 100644 --- a/tests/main/unt/hashbidimap.c +++ b/tests/unt/cmc/hashbidimap.h @@ -1,8 +1,9 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_ASHBIDIMAP_H +#define CMC_TESTS_UNT_CMC_ASHBIDIMAP_H -#include "../src/hashbidimap.c" +#include "../utl.h" + +#include "cmc/hashbidimap.h" struct hashbidimap_fkey *hbm_fkey = &(struct hashbidimap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp @@ -23,7 +24,7 @@ struct hashbidimap_fval *hbm_fval_counter = &(struct hashbidimap_fval){ struct cmc_alloc_node *hbm_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; -CMC_CREATE_UNIT(HashBidiMap, true, { +CMC_CREATE_UNIT(CMCHashBidiMap, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashbidimap *map = hbm_new(943722, 0.6, hbm_fkey, hbm_fval); @@ -34,7 +35,10 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hbm_fkey, map->f_key); cmc_assert_equals(ptr, hbm_fval, map->f_val); - cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); cmc_assert_equals(ptr, NULL, map->callbacks); cmc_assert_greater_equals(size_t, (943722 / 0.6), hbm_capacity(map)); @@ -162,7 +166,10 @@ CMC_CREATE_UNIT(HashBidiMap, true, { cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); cmc_assert_equals(ptr, NULL, map->callbacks); hbm_free(map); @@ -793,7 +800,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, { }); }); -CMC_CREATE_UNIT(HashBidiMapIter, true, { +CMC_CREATE_UNIT(CMCHashBidiMapIter, true, { CMC_CREATE_TEST(PFX##_iter_start, { // WIP cmc_assert(true); @@ -804,14 +811,16 @@ CMC_CREATE_UNIT(HashBidiMapIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = HashBidiMap() + HashBidiMapIter(); + int result = CMCHashBidiMap() + CMCHashBidiMapIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | HashBidiMap Suit : %-42s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCHashBidiMap Suit : %-42s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_ASHBIDIMAP_H */ diff --git a/tests/main/unt/hashmap.c b/tests/unt/cmc/hashmap.h similarity index 87% rename from tests/main/unt/hashmap.c rename to tests/unt/cmc/hashmap.h index 868da06..a0710a2 100644 --- a/tests/main/unt/hashmap.c +++ b/tests/unt/cmc/hashmap.h @@ -1,8 +1,9 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_ASHMAP_H +#define CMC_TESTS_UNT_CMC_ASHMAP_H -#include "../src/hashmap.c" +#include "../utl.h" + +#include "cmc/hashmap.h" struct hashmap_fkey *hm_fkey = &(struct hashmap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp @@ -23,7 +24,7 @@ struct hashmap_fval *hm_fval_counter = &(struct hashmap_fval){ struct cmc_alloc_node *hm_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; -CMC_CREATE_UNIT(HashMap, true, { +CMC_CREATE_UNIT(CMCHashMap, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashmap *map = hm_new(943722, 0.6, hm_fkey, hm_fval); @@ -34,7 +35,10 @@ CMC_CREATE_UNIT(HashMap, true, { cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hm_fkey, map->f_key); cmc_assert_equals(ptr, hm_fval, map->f_val); - cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); cmc_assert_equals(ptr, NULL, map->callbacks); cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(map)); @@ -90,70 +94,73 @@ CMC_CREATE_UNIT(HashMap, true, { cmc_assert_equals(ptr, NULL, map); }); - // CMC_CREATE_TEST(PFX##_init(), { - // struct hashmap map = hm_init(943722, 0.6, hm_fkey, hm_fval); + CMC_CREATE_TEST(PFX##_init(), { + struct hashmap map = hm_init(943722, 0.6, hm_fkey, hm_fval); - // cmc_assert_not_equals(ptr, NULL, map.buffer); - // cmc_assert_equals(size_t, 0, map.count); - // cmc_assert_equals(double, 0.6, map.load); - // cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag); - // cmc_assert_equals(ptr, hm_fkey, map.f_key); - // cmc_assert_equals(ptr, hm_fval, map.f_val); - // cmc_assert_equals(ptr, &cmc_alloc_node_default, map.alloc); - // cmc_assert_equals(ptr, NULL, map.callbacks); + cmc_assert_not_equals(ptr, NULL, map.buffer); + cmc_assert_equals(size_t, 0, map.count); + cmc_assert_equals(double, 0.6, map.load); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag); + cmc_assert_equals(ptr, hm_fkey, map.f_key); + cmc_assert_equals(ptr, hm_fval, map.f_val); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map.alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map.alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map.alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, map.alloc->free); + cmc_assert_equals(ptr, NULL, map.callbacks); - // cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); + cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); - // hm_release(map); + hm_release(map); - // map = hm_init(0, 0.6, hm_fkey, hm_fval); - // cmc_assert_equals(ptr, NULL, map.buffer); + map = hm_init(0, 0.6, hm_fkey, hm_fval); + cmc_assert_equals(ptr, NULL, map.buffer); - // map = hm_init(UINT64_MAX, 0.99, hm_fkey, hm_fval); - // cmc_assert_equals(ptr, NULL, map.buffer); + map = hm_init(UINT64_MAX, 0.99, hm_fkey, hm_fval); + cmc_assert_equals(ptr, NULL, map.buffer); - // map = hm_init(1000, 0.6, hm_fkey, NULL); - // cmc_assert_equals(ptr, NULL, map.buffer); + map = hm_init(1000, 0.6, hm_fkey, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); - // map = hm_init(1000, 0.6, NULL, hm_fval); - // cmc_assert_equals(ptr, NULL, map.buffer); + map = hm_init(1000, 0.6, NULL, hm_fval); + cmc_assert_equals(ptr, NULL, map.buffer); - // map = hm_init(1000, 0.6, NULL, NULL); - // cmc_assert_equals(ptr, NULL, map.buffer); - // }); + map = hm_init(1000, 0.6, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + }); - // CMC_CREATE_TEST(PFX##_init_custom(), { - // struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, - // hm_alloc_node, callbacks); + CMC_CREATE_TEST(PFX##_init_custom(), { + struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, + hm_alloc_node, callbacks); - // cmc_assert_not_equals(ptr, NULL, map.buffer); - // cmc_assert_equals(size_t, 0, map.count); - // cmc_assert_equals(double, 0.6, map.load); - // cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag); - // cmc_assert_equals(ptr, hm_fkey, map.f_key); - // cmc_assert_equals(ptr, hm_fval, map.f_val); - // cmc_assert_equals(ptr, hm_alloc_node, map.alloc); - // cmc_assert_equals(ptr, callbacks, map.callbacks); + cmc_assert_not_equals(ptr, NULL, map.buffer); + cmc_assert_equals(size_t, 0, map.count); + cmc_assert_equals(double, 0.6, map.load); + cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag); + cmc_assert_equals(ptr, hm_fkey, map.f_key); + cmc_assert_equals(ptr, hm_fval, map.f_val); + cmc_assert_equals(ptr, hm_alloc_node, map.alloc); + cmc_assert_equals(ptr, callbacks, map.callbacks); - // cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); + cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); - // hm_release(map); + hm_release(map); - // map = hm_init_custom(0, 0.6, hm_fkey, hm_fval, NULL, NULL); - // cmc_assert_equals(ptr, NULL, map.buffer); + map = hm_init_custom(0, 0.6, hm_fkey, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); - // map = hm_init_custom(UINT64_MAX, 0.99, hm_fkey, hm_fval, NULL, NULL); - // cmc_assert_equals(ptr, NULL, map.buffer); + map = hm_init_custom(UINT64_MAX, 0.99, hm_fkey, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); - // map = hm_init_custom(1000, 0.6, hm_fkey, NULL, NULL, NULL); - // cmc_assert_equals(ptr, NULL, map.buffer); + map = hm_init_custom(1000, 0.6, hm_fkey, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); - // map = hm_init_custom(1000, 0.6, NULL, hm_fval, NULL, NULL); - // cmc_assert_equals(ptr, NULL, map.buffer); + map = hm_init_custom(1000, 0.6, NULL, hm_fval, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); - // map = hm_init_custom(1000, 0.6, NULL, NULL, NULL, NULL); - // cmc_assert_equals(ptr, NULL, map.buffer); - // }); + map = hm_init_custom(1000, 0.6, NULL, NULL, NULL, NULL); + cmc_assert_equals(ptr, NULL, map.buffer); + }); CMC_CREATE_TEST(PFX##_clear(), { k_total_free = 0; @@ -217,35 +224,35 @@ CMC_CREATE_UNIT(HashMap, true, { v_total_free = 0; }); - // CMC_CREATE_TEST(PFX##_release(), { - // k_total_free = 0; - // v_total_free = 0; - // struct hashmap map = - // hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter); + CMC_CREATE_TEST(PFX##_release(), { + k_total_free = 0; + v_total_free = 0; + struct hashmap map = + hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter); - // cmc_assert_not_equals(ptr, NULL, map.buffer); + cmc_assert_not_equals(ptr, NULL, map.buffer); - // for (size_t i = 1; i <= 1000; i++) - // hm_insert(&map, i, i); + for (size_t i = 1; i <= 1000; i++) + hm_insert(&map, i, i); - // cmc_assert_equals(size_t, 1000, map.count); + cmc_assert_equals(size_t, 1000, map.count); - // hm_release(map); + hm_release(map); - // cmc_assert_equals(int32_t, 1000, k_total_free); - // cmc_assert_equals(int32_t, 1000, v_total_free); + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); - // map = hm_init(1000, 0.6, hm_fkey_counter, hm_fval_counter); + map = hm_init(1000, 0.6, hm_fkey_counter, hm_fval_counter); - // cmc_assert_not_equals(ptr, NULL, map.buffer); + cmc_assert_not_equals(ptr, NULL, map.buffer); - // hm_release(map); + hm_release(map); - // cmc_assert_equals(int32_t, 1000, k_total_free); - // cmc_assert_equals(int32_t, 1000, v_total_free); - // k_total_free = 0; - // v_total_free = 0; - // }); + cmc_assert_equals(int32_t, 1000, k_total_free); + cmc_assert_equals(int32_t, 1000, v_total_free); + k_total_free = 0; + v_total_free = 0; + }); CMC_CREATE_TEST(PFX##_customize(), { struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); @@ -262,7 +269,10 @@ CMC_CREATE_UNIT(HashMap, true, { map->flag = CMC_FLAG_ERROR; hm_customize(map, NULL, NULL); - cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); cmc_assert_equals(ptr, NULL, map->callbacks); cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); @@ -370,8 +380,8 @@ CMC_CREATE_UNIT(HashMap, true, { for (size_t i = 0; i < 6; i++) cmc_assert(hm_insert(map, i, i)); - for (size_t i = 0; i < 6; i++) - cmc_assert_equals(size_t, i, hm_impl_get_entry(map, i)->dist); + // for (size_t i = 0; i < 6; i++) + // cmc_assert_equals(size_t, i, hm_impl_get_entry(map, i)->dist); hm_fkey->hash = cmc_size_hash; @@ -874,7 +884,7 @@ struct hashmap_fkey *hm_fkey_numhash = &(struct hashmap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(HashMapIter, true, { +CMC_CREATE_UNIT(CMCHashMapIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval); @@ -1318,14 +1328,16 @@ CMC_CREATE_UNIT(HashMapIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = HashMap() + HashMapIter(); + int result = CMCHashMap() + CMCHashMapIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | HashMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCHashMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_ASHMAP_H */ diff --git a/tests/main/unt/hashmultimap.c b/tests/unt/cmc/hashmultimap.h similarity index 97% rename from tests/main/unt/hashmultimap.c rename to tests/unt/cmc/hashmultimap.h index 15df5e2..343ff93 100644 --- a/tests/main/unt/hashmultimap.c +++ b/tests/unt/cmc/hashmultimap.h @@ -1,8 +1,9 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_ASHMULTIMAP_H +#define CMC_TESTS_UNT_CMC_ASHMULTIMAP_H -#include "../src/hashmultimap.c" +#include "../utl.h" + +#include "cmc/hashmultimap.h" struct hashmultimap_fkey *hmm_fkey = &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp @@ -23,7 +24,7 @@ struct hashmultimap_fval *hmm_fval_counter = &(struct hashmultimap_fval){ struct cmc_alloc_node *hmm_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; -CMC_CREATE_UNIT(HashMultiMap, true, { +CMC_CREATE_UNIT(CMCHashMultiMap, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashmultimap *map = hmm_new(943722, 0.6, hmm_fkey, hmm_fval); @@ -34,7 +35,10 @@ CMC_CREATE_UNIT(HashMultiMap, true, { cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); cmc_assert_equals(ptr, hmm_fkey, map->f_key); cmc_assert_equals(ptr, hmm_fval, map->f_val); - cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); cmc_assert_equals(ptr, NULL, map->callbacks); cmc_assert_greater_equals(size_t, (943722 / 0.6), hmm_capacity(map)); @@ -464,7 +468,7 @@ struct hashmultimap_fkey *hmm_fkey_numhash = &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(HashMultiMapIter, true, { +CMC_CREATE_UNIT(CMCHashMultiMapIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); @@ -908,14 +912,16 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = HashMultiMap() + HashMultiMapIter(); + int result = CMCHashMultiMap() + CMCHashMultiMapIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | HashMultiMap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCHashMultiMap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_ASHMULTIMAP_H */ diff --git a/tests/main/unt/hashmultiset.c b/tests/unt/cmc/hashmultiset.h similarity index 97% rename from tests/main/unt/hashmultiset.c rename to tests/unt/cmc/hashmultiset.h index 0992033..bb70897 100644 --- a/tests/main/unt/hashmultiset.c +++ b/tests/unt/cmc/hashmultiset.h @@ -1,8 +1,9 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_ASHMULTISET_H +#define CMC_TESTS_UNT_CMC_ASHMULTISET_H -#include "../src/hashmultiset.c" +#include "../utl.h" + +#include "cmc/hashmultiset.h" struct hashmultiset_fval *hms_fval = &(struct hashmultiset_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp @@ -15,7 +16,7 @@ struct hashmultiset_fval *hms_fval_counter = &(struct hashmultiset_fval){ struct cmc_alloc_node *hms_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; -CMC_CREATE_UNIT(HashMultiSet, true, { +CMC_CREATE_UNIT(CMCHashMultiSet, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashmultiset *set = hms_new(943722, 0.6, hms_fval); @@ -25,7 +26,10 @@ CMC_CREATE_UNIT(HashMultiSet, true, { cmc_assert_equals(double, 0.6, set->load); cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); cmc_assert_equals(ptr, hms_fval, set->f_val); - cmc_assert_equals(ptr, &cmc_alloc_node_default, set->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, set->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, set->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, set->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, set->alloc->free); cmc_assert_equals(ptr, NULL, set->callbacks); cmc_assert_greater_equals(size_t, (943722 / 0.6), hms_capacity(set)); @@ -418,7 +422,7 @@ struct hashmultiset_fval *hms_fval_numhash = &(struct hashmultiset_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(HashMultiSetIter, true, { +CMC_CREATE_UNIT(CMCHashMultiSetIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash); @@ -845,14 +849,16 @@ CMC_CREATE_UNIT(HashMultiSetIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = HashMultiSet() + HashMultiSetIter(); + int result = CMCHashMultiSet() + CMCHashMultiSetIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | HashMultiSet Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCHashMultiSet Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_ASHMULTISET_H */ diff --git a/tests/main/unt/hashset.c b/tests/unt/cmc/hashset.h similarity index 97% rename from tests/main/unt/hashset.c rename to tests/unt/cmc/hashset.h index 78e79a2..38e2933 100644 --- a/tests/main/unt/hashset.c +++ b/tests/unt/cmc/hashset.h @@ -1,8 +1,9 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_ASHSET_H +#define CMC_TESTS_UNT_CMC_ASHSET_H -#include "../src/hashset.c" +#include "../utl.h" + +#include "cmc/hashset.h" struct hashset_fval *hs_fval = &(struct hashset_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp @@ -15,7 +16,7 @@ struct hashset_fval *hs_fval_counter = &(struct hashset_fval){ struct cmc_alloc_node *hs_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; -CMC_CREATE_UNIT(HashSet, true, { +CMC_CREATE_UNIT(CMCHashSet, true, { CMC_CREATE_TEST(PFX##_new(), { struct hashset *set = hs_new(943722, 0.6, hs_fval); @@ -25,7 +26,10 @@ CMC_CREATE_UNIT(HashSet, true, { cmc_assert_equals(double, 0.6, set->load); cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); cmc_assert_equals(ptr, hs_fval, set->f_val); - cmc_assert_equals(ptr, &cmc_alloc_node_default, set->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, set->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, set->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, set->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, set->alloc->free); cmc_assert_equals(ptr, NULL, set->callbacks); cmc_assert_greater_equals(size_t, (943722 / 0.6), hs_capacity(set)); @@ -224,8 +228,8 @@ CMC_CREATE_UNIT(HashSet, true, { for (size_t i = 0; i < 6; i++) cmc_assert(hs_insert(set, i)); - for (size_t i = 0; i < 6; i++) - cmc_assert_equals(size_t, i, hs_impl_get_entry(set, i)->dist); + // for (size_t i = 0; i < 6; i++) + // cmc_assert_equals(size_t, i, hs_impl_get_entry(set, i)->dist); hs_fval->hash = cmc_size_hash; @@ -618,7 +622,7 @@ struct hashset_fval *hs_fval_numhash = &(struct hashset_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(HashSetIter, true, { +CMC_CREATE_UNIT(CMCHashSetIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct hashset *set = hs_new(100, 0.6, hs_fval_numhash); @@ -1025,14 +1029,16 @@ CMC_CREATE_UNIT(HashSetIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = HashSet() + HashSetIter(); + int result = CMCHashSet() + CMCHashSetIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | HashSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCHashSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_ASHSET_H */ diff --git a/tests/main/unt/heap.c b/tests/unt/cmc/heap.h similarity index 98% rename from tests/main/unt/heap.c rename to tests/unt/cmc/heap.h index 94f2fa8..ca320ef 100644 --- a/tests/main/unt/heap.c +++ b/tests/unt/cmc/heap.h @@ -1,14 +1,15 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_EAP_H +#define CMC_TESTS_UNT_CMC_EAP_H -#include "../src/heap.c" +#include "../utl.h" + +#include "cmc/heap.h" struct heap_fval *h_fval = &(struct heap_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(Heap, true, { +CMC_CREATE_UNIT(CMCHeap, true, { CMC_CREATE_TEST(new, { struct heap *h = h_new(1000000, CMC_MAX_HEAP, h_fval); @@ -286,7 +287,7 @@ CMC_CREATE_UNIT(Heap, true, { }); }); -CMC_CREATE_UNIT(HeapIter, true, { +CMC_CREATE_UNIT(CMCHeapIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); @@ -713,14 +714,16 @@ CMC_CREATE_UNIT(HeapIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = Heap() + HeapIter(); + int result = CMCHeap() + CMCHeapIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | Heap Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCHeap Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_EAP_H */ diff --git a/tests/main/unt/intervalheap.c b/tests/unt/cmc/intervalheap.h similarity index 96% rename from tests/main/unt/intervalheap.c rename to tests/unt/cmc/intervalheap.h index 9d3d06c..6b28430 100644 --- a/tests/main/unt/intervalheap.c +++ b/tests/unt/cmc/intervalheap.h @@ -1,8 +1,9 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_NTERVALHEAP_H +#define CMC_TESTS_UNT_CMC_NTERVALHEAP_H -#include "../src/intervalheap.c" +#include "../utl.h" + +#include "cmc/intervalheap.h" struct intervalheap_fval *ih_fval = &(struct intervalheap_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp @@ -15,7 +16,7 @@ struct intervalheap_fval *ih_fval_counter = &(struct intervalheap_fval){ struct cmc_alloc_node *ih_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; -CMC_CREATE_UNIT(IntervalHeap, true, { +CMC_CREATE_UNIT(CMCIntervalHeap, true, { CMC_CREATE_TEST(PFX##_new(), { struct intervalheap *ih = ih_new(1000000, ih_fval); @@ -86,7 +87,10 @@ CMC_CREATE_UNIT(IntervalHeap, true, { cmc_assert_not_equals(ptr, NULL, ih); cmc_assert_equals(size_t, 1, ih_capacity(ih)); - cmc_assert_equals(ptr, &cmc_alloc_node_default, ih->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, ih->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, ih->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, ih->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, ih->alloc->free); cmc_assert_equals(ptr, NULL, ih->callbacks); ih_free(ih); @@ -196,7 +200,10 @@ CMC_CREATE_UNIT(IntervalHeap, true, { ih->flag = CMC_FLAG_ERROR; ih_customize(ih, NULL, NULL); - cmc_assert_equals(ptr, &cmc_alloc_node_default, ih->alloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, ih->alloc->malloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, ih->alloc->calloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, ih->alloc->realloc); + cmc_assert_equals(ptr, cmc_alloc_node_default.free, ih->alloc->free); cmc_assert_equals(ptr, NULL, ih->callbacks); cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); @@ -603,7 +610,7 @@ CMC_CREATE_UNIT(IntervalHeap, true, { }); }); -CMC_CREATE_UNIT(IntervalHeapIter, true, { +CMC_CREATE_UNIT(CMCIntervalHeapIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct intervalheap *ih = ih_new(100, ih_fval); @@ -1032,14 +1039,16 @@ CMC_CREATE_UNIT(IntervalHeapIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = IntervalHeap() + IntervalHeapIter(); + int result = CMCIntervalHeap() + CMCIntervalHeapIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | IntervalHeap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCIntervalHeap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_NTERVALHEAP_H */ diff --git a/tests/main/unt/linkedlist.c b/tests/unt/cmc/linkedlist.h similarity index 98% rename from tests/main/unt/linkedlist.c rename to tests/unt/cmc/linkedlist.h index cc4989e..cb78499 100644 --- a/tests/main/unt/linkedlist.c +++ b/tests/unt/cmc/linkedlist.h @@ -1,14 +1,15 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_INKEDLIST_H +#define CMC_TESTS_UNT_CMC_INKEDLIST_H -#include "../src/linkedlist.c" +#include "../utl.h" + +#include "cmc/linkedlist.h" struct linkedlist_fval *ll_fval = &(struct linkedlist_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(LinkedList, true, { +CMC_CREATE_UNIT(CMCLinkedList, true, { CMC_CREATE_TEST(new, { struct linkedlist *ll = ll_new(ll_fval); @@ -339,7 +340,7 @@ CMC_CREATE_UNIT(LinkedList, true, { }); }); -CMC_CREATE_UNIT(LinkedListIter, true, { +CMC_CREATE_UNIT(CMCLinkedListIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct linkedlist *ll = ll_new(ll_fval); @@ -798,14 +799,16 @@ CMC_CREATE_UNIT(LinkedListIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = LinkedList() + LinkedListIter(); + int result = CMCLinkedList() + CMCLinkedListIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | LinkedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCLinkedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_INKEDLIST_H */ diff --git a/tests/main/unt/list.c b/tests/unt/cmc/list.h similarity index 98% rename from tests/main/unt/list.c rename to tests/unt/cmc/list.h index 2369b57..8bda4ac 100644 --- a/tests/main/unt/list.c +++ b/tests/unt/cmc/list.h @@ -1,14 +1,15 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_LIST_H +#define CMC_TESTS_UNT_CMC_LIST_H -#include "../src/list.c" +#include "../utl.h" + +#include "cmc/list.h" struct list_fval *l_fval = &(struct list_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(List, true, { +CMC_CREATE_UNIT(CMCList, true, { CMC_CREATE_TEST(new, { struct list *l = l_new(1000000, l_fval); @@ -610,7 +611,7 @@ CMC_CREATE_UNIT(List, true, { }); }) -CMC_CREATE_UNIT(ListIter, true, { +CMC_CREATE_UNIT(CMCListIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct list *l = l_new(100, l_fval); @@ -1065,14 +1066,16 @@ CMC_CREATE_UNIT(ListIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = List() + ListIter(); + int result = CMCList() + CMCListIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | List Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCList Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_LIST_H */ diff --git a/tests/main/unt/queue.c b/tests/unt/cmc/queue.h similarity index 98% rename from tests/main/unt/queue.c rename to tests/unt/cmc/queue.h index 990b386..b9a67b3 100644 --- a/tests/main/unt/queue.c +++ b/tests/unt/cmc/queue.h @@ -1,14 +1,15 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_QUEUE_H +#define CMC_TESTS_UNT_CMC_QUEUE_H -#include "../src/queue.c" +#include "../utl.h" + +#include "cmc/queue.h" struct queue_fval *q_fval = &(struct queue_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(Queue, true, { +CMC_CREATE_UNIT(CMCQueue, true, { CMC_CREATE_TEST(new, { struct queue *q = q_new(1000000, q_fval); @@ -538,7 +539,7 @@ CMC_CREATE_UNIT(Queue, true, { }); }); -CMC_CREATE_UNIT(QueueIter, true, { +CMC_CREATE_UNIT(CMCQueueIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct queue *q = q_new(100, q_fval); @@ -951,14 +952,16 @@ CMC_CREATE_UNIT(QueueIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = Queue() + QueueIter(); + int result = CMCQueue() + CMCQueueIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | Queue Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCQueue Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_QUEUE_H */ diff --git a/tests/main/unt/sortedlist.c b/tests/unt/cmc/sortedlist.h similarity index 97% rename from tests/main/unt/sortedlist.c rename to tests/unt/cmc/sortedlist.h index d21cca6..edb1b8c 100644 --- a/tests/main/unt/sortedlist.c +++ b/tests/unt/cmc/sortedlist.h @@ -1,14 +1,15 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_SORTEDLIST_H +#define CMC_TESTS_UNT_CMC_SORTEDLIST_H -#include "../src/sortedlist.c" +#include "../utl.h" + +#include "cmc/sortedlist.h" struct sortedlist_fval *sl_fval = &(struct sortedlist_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(SortedList, true, { +CMC_CREATE_UNIT(CMCSortedList, true, { CMC_CREATE_TEST(new, { struct sortedlist *sl = sl_new(1000000, sl_fval); @@ -308,7 +309,7 @@ CMC_CREATE_UNIT(SortedList, true, { }); }); -CMC_CREATE_UNIT(SortedListIter, true, { +CMC_CREATE_UNIT(CMCSortedListIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct sortedlist *sl = sl_new(100, sl_fval); @@ -698,14 +699,16 @@ CMC_CREATE_UNIT(SortedListIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = SortedList() + SortedListIter(); + int result = CMCSortedList() + CMCSortedListIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | SortedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCSortedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_SORTEDLIST_H */ diff --git a/tests/main/unt/stack.c b/tests/unt/cmc/stack.h similarity index 98% rename from tests/main/unt/stack.c rename to tests/unt/cmc/stack.h index 17f78e9..4efb1f4 100644 --- a/tests/main/unt/stack.c +++ b/tests/unt/cmc/stack.h @@ -1,14 +1,15 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_STACK_H +#define CMC_TESTS_UNT_CMC_STACK_H -#include "../src/stack.c" +#include "../utl.h" + +#include "cmc/stack.h" struct stack_fval *s_fval = &(struct stack_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(Stack, true, { +CMC_CREATE_UNIT(CMCStack, true, { CMC_CREATE_TEST(new, { struct stack *s = s_new(1000000, s_fval); @@ -402,7 +403,7 @@ CMC_CREATE_UNIT(Stack, true, { }); }); -CMC_CREATE_UNIT(StackIter, true, { +CMC_CREATE_UNIT(CMCStackIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct stack *s = s_new(100, s_fval); @@ -833,14 +834,16 @@ CMC_CREATE_UNIT(StackIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = Stack() + StackIter(); + int result = CMCStack() + CMCStackIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | Stack Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCStack Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_STACK_H */ diff --git a/tests/main/unt/treemap.c b/tests/unt/cmc/treemap.h similarity index 98% rename from tests/main/unt/treemap.c rename to tests/unt/cmc/treemap.h index 379407c..014ac02 100644 --- a/tests/main/unt/treemap.c +++ b/tests/unt/cmc/treemap.h @@ -1,8 +1,9 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_TREEMAP_H +#define CMC_TESTS_UNT_CMC_TREEMAP_H -#include "../src/treemap.c" +#include "../utl.h" + +#include "cmc/treemap.h" struct treemap_fkey *tm_fkey = &(struct treemap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp @@ -12,7 +13,7 @@ struct treemap_fval *tm_fval = &(struct treemap_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(TreeMap, true, { +CMC_CREATE_UNIT(CMCTreeMap, true, { CMC_CREATE_TEST(new, { struct treemap *map = tm_new(tm_fkey, tm_fval); @@ -207,7 +208,7 @@ CMC_CREATE_UNIT(TreeMap, true, { }); }); -CMC_CREATE_UNIT(TreeMapIter, true, { +CMC_CREATE_UNIT(CMCTreeMapIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct treemap *map = tm_new(tm_fkey, tm_fval); @@ -651,14 +652,16 @@ CMC_CREATE_UNIT(TreeMapIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = TreeMap() + TreeMapIter(); + int result = CMCTreeMap() + CMCTreeMapIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | TreeMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCTreeMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_TREEMAP_H */ diff --git a/tests/main/unt/treeset.c b/tests/unt/cmc/treeset.h similarity index 97% rename from tests/main/unt/treeset.c rename to tests/unt/cmc/treeset.h index cce4a14..46dddf6 100644 --- a/tests/main/unt/treeset.c +++ b/tests/unt/cmc/treeset.h @@ -1,14 +1,15 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_CMC_TREESET_H +#define CMC_TESTS_UNT_CMC_TREESET_H -#include "../src/treeset.c" +#include "../utl.h" + +#include "cmc/treeset.h" struct treeset_fval *ts_fval = &(struct treeset_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp }; -CMC_CREATE_UNIT(TreeSet, true, { +CMC_CREATE_UNIT(CMCTreeSet, true, { CMC_CREATE_TEST(new, { struct treeset *set = ts_new(ts_fval); @@ -162,7 +163,7 @@ CMC_CREATE_UNIT(TreeSet, true, { }); }); -CMC_CREATE_UNIT(TreeSetIter, true, { +CMC_CREATE_UNIT(CMCTreeSetIter, true, { CMC_CREATE_TEST(PFX##_iter_start(), { struct treeset *set = ts_new(ts_fval); @@ -569,14 +570,16 @@ CMC_CREATE_UNIT(TreeSetIter, true, { #ifdef CMC_TEST_MAIN int main(void) { - int result = TreeSet() + TreeSetIter(); + int result = CMCTreeSet() + CMCTreeSetIter(); printf(" +---------------------------------------------------------------+"); printf("\n"); - printf(" | TreeSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); + printf(" | CMCTreeSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); printf(" +---------------------------------------------------------------+"); printf("\n\n\n"); return result; } #endif + +#endif /* CMC_TESTS_UNT_CMC_TREESET_H */ diff --git a/tests/main/unt/utl.c b/tests/unt/utl.h similarity index 95% rename from tests/main/unt/utl.c rename to tests/unt/utl.h index 391e3b4..9835ae9 100644 --- a/tests/main/unt/utl.c +++ b/tests/unt/utl.h @@ -1,13 +1,16 @@ /* Utility file to be included in the unit tests */ -#ifndef CMC_UNIT_TEST_UTL__ -#define CMC_UNIT_TEST_UTL__ +#ifndef CMC_TESTS_UTL +#define CMC_TESTS_UTL #include #include #include #include "cor/hashtable.h" +#include "utl/assert.h" +#include "utl/foreach.h" #include "utl/futils.h" +#include "utl/test.h" size_t numhash(size_t a) { @@ -165,4 +168,4 @@ struct cmc_callbacks *callbacks = &(struct cmc_callbacks){ .create = callback_cr .delete = callback_delete, .resize = callback_resize }; -#endif /* CMC_UNIT_TEST_UTL__ */ +#endif /* CMC_TESTS_UTL */ diff --git a/tests/main/unt/foreach.c b/tests/unt/utl/foreach.h similarity index 97% rename from tests/main/unt/foreach.c rename to tests/unt/utl/foreach.h index a37bca4..2336f99 100644 --- a/tests/main/unt/foreach.c +++ b/tests/unt/utl/foreach.h @@ -1,25 +1,24 @@ -#include "utl.c" -#include "utl/assert.h" -#include "utl/test.h" +#ifndef CMC_TESTS_UNT_UTL_FOREACH_H +#define CMC_TESTS_UNT_UTL_FOREACH_H -#include "utl/foreach.h" +#include "../utl.h" -#include "../src/bitset.c" -#include "../src/deque.c" -#include "../src/hashbidimap.c" -#include "../src/hashmap.c" -#include "../src/hashmultimap.c" -#include "../src/hashmultiset.c" -#include "../src/hashset.c" -#include "../src/heap.c" -#include "../src/intervalheap.c" -#include "../src/linkedlist.c" -#include "../src/list.c" -#include "../src/queue.c" -#include "../src/sortedlist.c" -#include "../src/stack.c" -#include "../src/treemap.c" -#include "../src/treeset.c" +#include "cmc/bitset.h" +#include "cmc/deque.h" +#include "cmc/hashbidimap.h" +#include "cmc/hashmap.h" +#include "cmc/hashmultimap.h" +#include "cmc/hashmultiset.h" +#include "cmc/hashset.h" +#include "cmc/heap.h" +#include "cmc/intervalheap.h" +#include "cmc/linkedlist.h" +#include "cmc/list.h" +#include "cmc/queue.h" +#include "cmc/sortedlist.h" +#include "cmc/stack.h" +#include "cmc/treemap.h" +#include "cmc/treeset.h" CMC_CREATE_UNIT(ForEach, true, { // CMC_CREATE_TEST(CMC, { @@ -505,3 +504,5 @@ int main(void) return result; } #endif + +#endif /* CMC_TESTS_UNT_UTL_FOREACH_H */ From e08a8f89f323fe4578b23b5ed4a6655e5a08aebc Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 11 Jun 2020 22:04:23 -0300 Subject: [PATCH 31/51] Update autogen.py and travis --- .travis.yml | 2 +- autogen.py | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index d7ffa96..8efae36 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,6 @@ addons: script: - sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc - export CC=gcc-7 - - make coverage + - make after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/autogen.py b/autogen.py index ed5d58d..9afc512 100644 --- a/autogen.py +++ b/autogen.py @@ -1,4 +1,5 @@ -# A script that automatically expands the macros for code coverage +# A script that automatically generates code for code coverage, updates tests +# and Makefiles, and creates necessary directories import os import sys @@ -130,15 +131,21 @@ for ftype in ['HEADER', 'SOURCE']: os.remove(TMP_FILE) # Format all files -print('Formating files...') +from shutil import which -cmd = ['clang-format', '--style=file', '--verbose', '-i'] -dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{lib.lower()}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys() for lib in ALL_LIBS] +if which('clang-format') is not None: + print('clang-format found. Formating files...') -cmd.extend(dirs_to_format) -subprocess.call(cmd) + cmd = ['clang-format', '--style=file', '--verbose', '-i'] + dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{lib.lower()}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys() for lib in ALL_LIBS] + + cmd.extend(dirs_to_format) + subprocess.call(cmd) +else: + print('clang-format not found. Skipping code formatting...') # Makefile +# Contains many usefull things dealing with tests, code coverage and formatting BUILD_DIR = f'{OUTPUT_DIR}/build' OBJ_DIR = f'{BUILD_DIR}/obj' INCLUDE_DIR = f"{OUTPUT_DIR}/{DIR_MAP['HEADER']}" @@ -150,6 +157,8 @@ assert_dir(OBJ_DIR) for lib in ALL_LIBS: assert_dir(f'{OBJ_DIR}/{lib.lower()}') +print('Updating Makefile...') + file = open(f'Makefile', 'w') file.write(f'''# This file was generated by a Python script @@ -212,4 +221,4 @@ for data in collections: file.close() -print('Done') +print('\nDone') From 22ab6fdb64b9a0f648bfd70dddf80d9428f879f0 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 11 Jun 2020 22:11:22 -0300 Subject: [PATCH 32/51] Update .travis.yml --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8efae36..ded006a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -dist: trusty +dist: xenial os: linux language: c compiler: gcc @@ -12,6 +12,7 @@ addons: script: - sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc - export CC=gcc-7 - - make + - python3 autogen.py + - make coverage after_success: - bash <(curl -s https://codecov.io/bash) From 10e0b4b397fa698573aecde31a04aed0d3379012 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 11 Jun 2020 22:16:34 -0300 Subject: [PATCH 33/51] Update .travis.yml --- .travis.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index ded006a..f6c4d1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,16 +2,10 @@ dist: xenial os: linux language: c compiler: gcc -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-7 - - cmake +before_install: + - sudo apt-get -y update + - sudo apt-get -y install python3 gcc make script: - - sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc - - export CC=gcc-7 - python3 autogen.py - make coverage after_success: From 767fc0d7fd873f99e35f8a8e9d89ef9eb96c7521 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 11 Jun 2020 22:39:46 -0300 Subject: [PATCH 34/51] Update .travis.yml --- .travis.yml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index f6c4d1d..27f2ed8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,21 @@ dist: xenial os: linux language: c compiler: gcc -before_install: - - sudo apt-get -y update - - sudo apt-get -y install python3 gcc make +addons: + apt: + sources: + - deadsnakes + - ubuntu-toolchain-r-test + packages: + - gcc-9 + - cmake + - python3.8 script: - - python3 autogen.py + - sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc + - export CC=gcc-7 + - gcc --version + - python3 --version + - python3.8 autogen.py - make coverage after_success: - bash <(curl -s https://codecov.io/bash) From 203516d8cf47e7fcd030e9a8cb7303ff5138b15e Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 12 Jun 2020 12:34:33 -0300 Subject: [PATCH 35/51] v0.24.0 preview --- .travis.yml | 10 +-- CHANGELOG | 18 +++++ README.md | 71 +++++++++++++++++++ benchmarks/C++ Comparison/hashtable/hashmap.c | 46 ++++++++++++ benchmarks/C++ Comparison/hashtable/script.py | 58 +++++++++++++++ .../C++ Comparison/hashtable/unorderedmap.cpp | 16 +++++ examples/sieve.c | 42 +++++++++++ 7 files changed, 256 insertions(+), 5 deletions(-) create mode 100644 benchmarks/C++ Comparison/hashtable/hashmap.c create mode 100644 benchmarks/C++ Comparison/hashtable/script.py create mode 100644 benchmarks/C++ Comparison/hashtable/unorderedmap.cpp create mode 100644 examples/sieve.c diff --git a/.travis.yml b/.travis.yml index 27f2ed8..7a47c6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,11 +12,11 @@ addons: - cmake - python3.8 script: - - sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc - - export CC=gcc-7 + - sudo ln -s /usr/bin/gcc-9 /usr/local/bin/gcc + - sudo ln -s /usr/bin/python3.8 /usr/local/bin/python + - export CC=gcc-9 - gcc --version - - python3 --version - - python3.8 autogen.py - - make coverage + - python --version + - make after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/CHANGELOG b/CHANGELOG index 922e52d..b125b5b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,22 @@ # RELEASE.MAJOR.MINOR +0.24.0 + A lot of breaking changes, with the library more modular now + Comeback of PUBLIC and PRIVATE for the CMC sub-library + Callbacks are now optional and can be turned off by defining CMC_NO_CALLBACKS + Added EXT library + New macro CMC_CAMEL_CASE can change the library's style where the default is snake case + Added: + ./cor/alloc.h + ./cor/callbacks.h + ./cor/heap.h + Complete rework of tests and code coverage + Removed cmc_flags, where now every flag is an enum (CMC_FLAGS_OK, CMC_FLAGS_ERROR, etc) + Different include guards + New way to generate code using PARAM + Code now completely changed by using the CMC_ macro to concatenate tokens + Token concatenation with SNAME now uses special macros that allow customization of the suffixes + 0.23.1 Added ./cor/bitset.h Added foreach tests @@ -8,6 +25,7 @@ 0.23.0 Added ./cmc/bitset.h + Added ./cor/flags.h Added ./utl/futils.h Added ./utl/mutex.h Added ./utl/thread.h diff --git a/README.md b/README.md index d85b64f..efd7eec 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,77 @@ ## Table of Contents +* Installation +* Usage +* Contributing +* License +* Features + +## Installation + +No installation is required. The entire library is made of header files and can be directly included into your project. + +## Usage + +The header `macro_collections.h` includes every feature from the library and comes with higher level APIs that help you generate collections from specific sub-libraries with specific extensions. + +```c +// WIP +#include "macro_collections.h" + +// A PARAM is a standard way to pass required parameters to the lower level API. +// It is a tuple of form (PFX, SNAME, SIZE, K, V). In this case, not all of them +// are used, so we can leave them empty. +#define MY_LIST_PARAMS (si32, stacki32, , , int32_t) + +// High level API. Generate a LIST from the CMC library with the STR extension +C_MACRO_COLLECTIONS_GEN(PUBLIC, CMC, LIST, MY_LIST_PARAMS, (STR)) + +bool int_str(FILE *fptr, int val) +{ + return 0 <= fprintf(fptr, "%d", val); +} + +int main(void) +{ + struct stack_int *stack = sint_new(100, &(struct stack_int_fval) { .str = int_str }); + + si32_free(stack); +} + +``` + +## Contributing + +## Features + +The C Macro Collections library is organized into many other sub-libraries. The following table is a quick overview. + +| Library | Name | Description | +| :-----: | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| CMC | The main C Macro Collections | The main library with variably-sized collections | +| COR | Core | Core functionalities used by more than one collection, usually from different sub-libraries | +| EXT | Extensions | Extension to collections from CMC, SAC and TSC libraries | +| INT | Integrations | Macros that facilitate the creation of code that involves more than one type of collection, e.g. transforming a set to a list | +| SAC | Statically Allocated Collections | Collections with a fixed sized array that don't use any heap allocation | +| TSC | Thread-Safe Collections | Collections that allow multiple operations from multiple threads | +| UTL | Utilities | Utilities for the library | + +Every macro that generates code for a certain collection can be found with the following template. Some exceptions exist as certain collections don't have or can't have some features. One big example is the `UTL` library, which does not follow this pattern. + +``` +macro_name := CMC_[ lib ]_[ collection ]_[ part ]_[ file ] + +lib := CMC | COR | DEV | EXT | INT | SAC | TSC +collection := BITSET | DEQUE | HASHBIDIMAP | HASHMAP | HASHMULTIMAP | HASHMULTISET | HASHSET | HEAP | INTERVALHEAP | LINKEDLIST | LIST | QUEUE | SORTEDLIST | STACK | TREEBIDIMAP | TREEMAP | TREEMULTIMAP | TREEMULTISET | TREESET +part := CORE | ITER | INIT | SETF | NODE ... +file := HEADER | SOURCE +``` + +__Some `collection`s might not be present in a certain `lib`. Check the documentation.__ + +Every macro is suffixed by `CMC` and each section is separated by an underscore (`_`). The first section is the library (`lib`). The second is the collection name in all uppercase. Then the `part` (or which feature from it) that you wish to generate. And last, if it is code that should belong to a header file or code that should belong to a source file. + * Project Structure * Available Collections * Features diff --git a/benchmarks/C++ Comparison/hashtable/hashmap.c b/benchmarks/C++ Comparison/hashtable/hashmap.c new file mode 100644 index 0000000..d2c4dbe --- /dev/null +++ b/benchmarks/C++ Comparison/hashtable/hashmap.c @@ -0,0 +1,46 @@ +#ifndef COUNT +#error "Please define COUNT" +#endif + +#include "cmc/hashmap.h" + +CMC_CMC_HASHMAP_CORE(PUBLIC, HEADER, (hmi32, hashmapi32, , int32_t, int32_t)) +CMC_CMC_HASHMAP_CORE(PUBLIC, SOURCE, (hmi32, hashmapi32, , int32_t, int32_t)) + +int cmp(int32_t a, int32_t b) +{ + return (a > b) - (a < b); +} + +size_t hash(int32_t a) +{ + size_t x = (size_t)a; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = (x >> 16) ^ x; + return x; +} + +struct hashmapi32_fkey *fkey = &(struct hashmapi32_fkey) { + .cmp = cmp, + .hash = hash, + NULL +}; + +struct hashmapi32_fval *fval = &(struct hashmapi32_fval) { + .cmp = cmp, + .hash = hash, + NULL +}; + +int main(void) +{ + struct hashmapi32 *map = hmi32_new(COUNT, 0.6, fkey, fval); + + for (int32_t i = 0; i < COUNT; i++) + hmi32_insert(map, i, i); + + hmi32_free(map); + + return 0; +} diff --git a/benchmarks/C++ Comparison/hashtable/script.py b/benchmarks/C++ Comparison/hashtable/script.py new file mode 100644 index 0000000..bcda9fb --- /dev/null +++ b/benchmarks/C++ Comparison/hashtable/script.py @@ -0,0 +1,58 @@ +import sys +import time +import subprocess + +ITERATIONS = 10 +VERBOSE = False + +NL = '\n' + +INCLUDE = "../../../src" +CC = 'gcc' +CCPP = 'g++' # LoL +OPT = '-O3' +COUNT = 2000000 + +# Common args +args = ['-I', INCLUDE, OPT, f'-DCOUNT={COUNT}', '-DCMC_NO_CALLBACKS'] + +c_args = [CC, 'hashmap.c', '-o', 'hashmap.exe'] +cpp_args = [CCPP, 'unorderedmap.cpp', '-I', INCLUDE, '-o', 'unorderedmap.exe', OPT, f'-DCOUNT={COUNT}'] + +c_args.extend(args) +cpp_args.extend(args) + +subprocess.check_output(c_args) +subprocess.check_output(cpp_args) + +total = 0 +for i in range(ITERATIONS): + print(f'{i}...', end='') + sys.stdout.flush() + start_time = time.time() + subprocess.call(['./hashmap.exe']) + + delta = time.time() - start_time + total += delta + + if VERBOSE: + print(f'({delta})') + +avg = int(((total / ITERATIONS) * 1e9) / COUNT) +print(f'{"" if VERBOSE else NL}{total / ITERATIONS} seconds for {COUNT} -> AVG[{avg} ns] [hashmap.exe]{NL if VERBOSE else ""}') + +total = 0 +for i in range(ITERATIONS): + print(f'{i}...', end='') + sys.stdout.flush() + start_time = time.time() + subprocess.call(['./unorderedmap.exe']) + + delta = time.time() - start_time + total += delta + + if VERBOSE: + print(f'({delta})') + +avg = int(((total / ITERATIONS) * 1e9) / COUNT) +print(f'{"" if VERBOSE else NL}{total / ITERATIONS} seconds for {COUNT} -> AVG[{avg} ns] [unorderedmap.exe]{NL if VERBOSE else ""}') diff --git a/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp b/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp new file mode 100644 index 0000000..72cbf0b --- /dev/null +++ b/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp @@ -0,0 +1,16 @@ +#ifndef COUNT +#error "Please define COUNT" +#endif + +#include +#include + +int main(void) +{ + std::unordered_map map(COUNT); + + for (int32_t i = 0; i < COUNT; i++) + map.insert({i, i}); + + return 0; +} diff --git a/examples/sieve.c b/examples/sieve.c new file mode 100644 index 0000000..131f76b --- /dev/null +++ b/examples/sieve.c @@ -0,0 +1,42 @@ +#include +#include "cmc/bitset.h" + +CMC_CMC_BITSET_CORE(PUBLIC, HEADER, (bs, bitset)) +CMC_CMC_BITSET_CORE(PUBLIC, SOURCE, (bs, bitset)) + +// All the prime numbers up to 1 billion +// With -O3: +// 28.583 s runtime +// 120 MB RAM +// 490 MB file size +int main(void) +{ + const size_t n = 1000000000; + + struct bitset *set = bs_new(n); + + if (!set) + return 1; + + bs_set_range(set, 0, n); + + size_t up_to = sqrt((double)n) + 1; + for (size_t i = 2; i < up_to; ++i) + { + if (bs_get(set, i)) + { + for (size_t j = 2 * i; j < n; j += i) + bs_clear(set, j); + } + } + + FILE *file = fopen("primes.txt", "w"); + + for (size_t i = 2; i < n; i++) + { + if (bs_get(set, i)) + fprintf(file, "%" PRIuMAX " ", i); + } + + fclose(file); +} From 922d8b01b8ec62fcc0207b1f79a12b9d8c6b8a23 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 16 Jun 2020 23:38:20 -0300 Subject: [PATCH 36/51] Update types.c --- tests/types.c | 279 +++++++++++++++++++++++++++----------------------- 1 file changed, 151 insertions(+), 128 deletions(-) diff --git a/tests/types.c b/tests/types.c index 9ee6797..60374e2 100644 --- a/tests/types.c +++ b/tests/types.c @@ -24,144 +24,167 @@ typedef union union_u { char *d; } union_t; -typedef int (*func_t)(int, double, char *); +typedef int (func_t)(int, double, char *); -CMC_COLLECTION_GENERATE(LIST, l0, list0, /* K */, struct_t *) -CMC_COLLECTION_GENERATE(STACK, s0, stack0, /* K */, struct_t *) -CMC_COLLECTION_GENERATE(QUEUE, q0, queue0, /* K */, struct_t *) -CMC_COLLECTION_GENERATE(DEQUE, d0, deque0, /* K */, struct_t *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll0, linked0, /* K */, struct_t *) -CMC_COLLECTION_GENERATE(HEAP, h0, heap0, /* K */, struct_t *) -CMC_COLLECTION_GENERATE(TREESET, ts0, tset0, /* K */, struct_t *) -CMC_COLLECTION_GENERATE(TREEMAP, tm0, tmap0, struct_t *, struct_t *) -CMC_COLLECTION_GENERATE(HASHSET, hs0, hset0, /* K */, struct_t *) -CMC_COLLECTION_GENERATE(HASHMAP, hm0, hmap0, struct_t *, struct_t *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih0, iheap0, struct_t *, struct_t *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm0, mmap0, struct_t *, struct_t *) -CMC_COLLECTION_GENERATE(MULTISET, ms0, mset0, struct_t *, struct_t *) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d0, deque0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm0, hashbidimap0, , struct_t *, struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm0, hashmap0, , struct_t *, struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm0, hashmultimap0, , struct_t *, struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms0, hashmultiset0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs0, hashset0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h0, heap0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih0, intervalheap0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll0, linkedlist0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l0, list0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q0, queue0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl0, sortedlist0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s0, stack0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm0, treemap0, , struct_t *, struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts0, treeset0, , , struct_t *)) -CMC_COLLECTION_GENERATE(LIST, l1, list1, /* K */, struct_t) -CMC_COLLECTION_GENERATE(STACK, s1, stack1, /* K */, struct_t) -CMC_COLLECTION_GENERATE(QUEUE, q1, queue1, /* K */, struct_t) -CMC_COLLECTION_GENERATE(DEQUE, d1, deque1, /* K */, struct_t) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll1, linked1, /* K */, struct_t) -CMC_COLLECTION_GENERATE(HEAP, h1, heap1, /* K */, struct_t) -CMC_COLLECTION_GENERATE(TREESET, ts1, tset1, /* K */, struct_t) -CMC_COLLECTION_GENERATE(TREEMAP, tm1, tmap1, struct_t, struct_t) -CMC_COLLECTION_GENERATE(HASHSET, hs1, hset1, /* K */, struct_t) -CMC_COLLECTION_GENERATE(HASHMAP, hm1, hmap1, struct_t, struct_t) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih1, iheap1, struct_t, struct_t) -CMC_COLLECTION_GENERATE(MULTIMAP, mm1, mmap1, struct_t, struct_t) -CMC_COLLECTION_GENERATE(MULTISET, ms1, mset1, struct_t, struct_t) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d1, deque1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm1, hashbidimap1, , struct_t, struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm1, hashmap1, , struct_t, struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm1, hashmultimap1, , struct_t, struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms1, hashmultiset1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs1, hashset1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h1, heap1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih1, intervalheap1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll1, linkedlist1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l1, list1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q1, queue1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl1, sortedlist1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s1, stack1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm1, treemap1, , struct_t, struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts1, treeset1, , , struct_t)) -CMC_COLLECTION_GENERATE(LIST, l2, list2, /* K */, int) -CMC_COLLECTION_GENERATE(STACK, s2, stack2, /* K */, int) -CMC_COLLECTION_GENERATE(QUEUE, q2, queue2, /* K */, int) -CMC_COLLECTION_GENERATE(DEQUE, d2, deque2, /* K */, int) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll2, linked2, /* K */, int) -CMC_COLLECTION_GENERATE(HEAP, h2, heap2, /* K */, int) -CMC_COLLECTION_GENERATE(TREESET, ts2, tset2, /* K */, int) -CMC_COLLECTION_GENERATE(TREEMAP, tm2, tmap2, int, int) -CMC_COLLECTION_GENERATE(HASHSET, hs2, hset2, /* K */, int) -CMC_COLLECTION_GENERATE(HASHMAP, hm2, hmap2, int, int) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih2, iheap2, /* K */, int) -CMC_COLLECTION_GENERATE(MULTIMAP, mm2, mmap2, int, int) -CMC_COLLECTION_GENERATE(MULTISET, ms2, mset2, /* K */, int) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d2, deque2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm2, hashbidimap2, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm2, hashmap2, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm2, hashmultimap2, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms2, hashmultiset2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs2, hashset2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h2, heap2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih2, intervalheap2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll2, linkedlist2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l2, list2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q2, queue2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl2, sortedlist2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s2, stack2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm2, treemap2, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts2, treeset2, , , int)) -CMC_COLLECTION_GENERATE(LIST, l3, list3, /* K */, int *) -CMC_COLLECTION_GENERATE(STACK, s3, stack3, /* K */, int *) -CMC_COLLECTION_GENERATE(QUEUE, q3, queue3, /* K */, int *) -CMC_COLLECTION_GENERATE(DEQUE, d3, deque3, /* K */, int *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll3, linked3, /* K */, int *) -CMC_COLLECTION_GENERATE(HEAP, h3, heap3, /* K */, int *) -CMC_COLLECTION_GENERATE(TREESET, ts3, tset3, /* K */, int *) -CMC_COLLECTION_GENERATE(TREEMAP, tm3, tmap3, int *, int *) -CMC_COLLECTION_GENERATE(HASHSET, hs3, hset3, /* K */, int *) -CMC_COLLECTION_GENERATE(HASHMAP, hm3, hmap3, int *, int *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih3, iheap3, /* K */, int *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm3, mmap3, int *, int *) -CMC_COLLECTION_GENERATE(MULTISET, ms3, mset3, /* K */, int *) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d3, deque3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm3, hashbidimap3, , int *, int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm3, hashmap3, , int *, int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm3, hashmultimap3, , int *, int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms3, hashmultiset3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs3, hashset3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h3, heap3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih3, intervalheap3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll3, linkedlist3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l3, list3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q3, queue3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl3, sortedlist3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s3, stack3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm3, treemap3, , int *, int *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts3, treeset3, , , int *)) -CMC_COLLECTION_GENERATE(LIST, l4, list4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(STACK, s4, stack4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(QUEUE, q4, queue4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(DEQUE, d4, deque4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll4, linked4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(HEAP, h4, heap4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(TREESET, ts4, tset4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(TREEMAP, tm4, tmap4, enum_t *, enum_t *) -CMC_COLLECTION_GENERATE(HASHSET, hs4, hset4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(HASHMAP, hm4, hmap4, enum_t *, enum_t *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih4, iheap4, /* K */, enum_t *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm4, mmap4, enum_t *, enum_t *) -CMC_COLLECTION_GENERATE(MULTISET, ms4, mset4, /* K */, enum_t *) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d4, deque4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm4, hashbidimap4, , enum_t, enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm4, hashmap4, , enum_t, enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm4, hashmultimap4, , enum_t, enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms4, hashmultiset4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs4, hashset4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h4, heap4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih4, intervalheap4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll4, linkedlist4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l4, list4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q4, queue4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl4, sortedlist4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s4, stack4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm4, treemap4, , enum_t, enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts4, treeset4, , , enum_t)) -CMC_COLLECTION_GENERATE(LIST, l5, list5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(STACK, s5, stack5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(QUEUE, q5, queue5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(DEQUE, d5, deque5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll5, linked5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(HEAP, h5, heap5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(TREESET, ts5, tset5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(TREEMAP, tm5, tmap5, enum_t, enum_t) -CMC_COLLECTION_GENERATE(HASHSET, hs5, hset5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(HASHMAP, hm5, hmap5, enum_t, enum_t) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih5, iheap5, /* K */, enum_t) -CMC_COLLECTION_GENERATE(MULTIMAP, mm5, mmap5, enum_t, enum_t) -CMC_COLLECTION_GENERATE(MULTISET, ms5, mset5, /* K */, enum_t) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d5, deque5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm5, hashbidimap5, , enum_t *, enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm5, hashmap5, , enum_t *, enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm5, hashmultimap5, , enum_t *, enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms5, hashmultiset5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs5, hashset5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h5, heap5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih5, intervalheap5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll5, linkedlist5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l5, list5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q5, queue5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl5, sortedlist5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s5, stack5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm5, treemap5, , enum_t *, enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts5, treeset5, , , enum_t *)) -CMC_COLLECTION_GENERATE(LIST, l6, list6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(STACK, s6, stack6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(QUEUE, q6, queue6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(DEQUE, d6, deque6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll6, linked6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(HEAP, h6, heap6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(TREESET, ts6, tset6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(TREEMAP, tm6, tmap6, union_t *, union_t *) -CMC_COLLECTION_GENERATE(HASHSET, hs6, hset6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(HASHMAP, hm6, hmap6, union_t *, union_t *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih6, iheap6, /* K */, union_t *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm6, mmap6, union_t *, union_t *) -CMC_COLLECTION_GENERATE(MULTISET, ms6, mset6, /* K */, union_t *) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d6, deque6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm6, hashbidimap6, , union_t, union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm6, hashmap6, , union_t, union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm6, hashmultimap6, , union_t, union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms6, hashmultiset6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs6, hashset6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h6, heap6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih6, intervalheap6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll6, linkedlist6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l6, list6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q6, queue6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl6, sortedlist6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s6, stack6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm6, treemap6, , union_t, union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts6, treeset6, , , union_t)) -CMC_COLLECTION_GENERATE(LIST, l7, list7, /* K */, union_t) -CMC_COLLECTION_GENERATE(STACK, s7, stack7, /* K */, union_t) -CMC_COLLECTION_GENERATE(QUEUE, q7, queue7, /* K */, union_t) -CMC_COLLECTION_GENERATE(DEQUE, d7, deque7, /* K */, union_t) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll7, linked7, /* K */, union_t) -CMC_COLLECTION_GENERATE(HEAP, h7, heap7, /* K */, union_t) -CMC_COLLECTION_GENERATE(TREESET, ts7, tset7, /* K */, union_t) -CMC_COLLECTION_GENERATE(TREEMAP, tm7, tmap7, union_t, union_t) -CMC_COLLECTION_GENERATE(HASHSET, hs7, hset7, /* K */, union_t) -CMC_COLLECTION_GENERATE(HASHMAP, hm7, hmap7, union_t, union_t) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih7, iheap7, /* K */, union_t) -CMC_COLLECTION_GENERATE(MULTIMAP, mm7, mmap7, union_t, union_t) -CMC_COLLECTION_GENERATE(MULTISET, ms7, mset7, /* K */, union_t) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d7, deque7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm7, hashbidimap7, , union_t *, union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm7, hashmap7, , union_t *, union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm7, hashmultimap7, , union_t *, union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms7, hashmultiset7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs7, hashset7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h7, heap7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih7, intervalheap7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll7, linkedlist7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l7, list7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q7, queue7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl7, sortedlist7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s7, stack7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm7, treemap7, , union_t *, union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts7, treeset7, , , union_t *)) -CMC_COLLECTION_GENERATE(LIST, l8, list8, /* K */, func_t) -CMC_COLLECTION_GENERATE(STACK, s8, stack8, /* K */, func_t) -CMC_COLLECTION_GENERATE(QUEUE, q8, queue8, /* K */, func_t) -CMC_COLLECTION_GENERATE(DEQUE, d8, deque8, /* K */, func_t) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll8, linked8, /* K */, func_t) -CMC_COLLECTION_GENERATE(HEAP, h8, heap8, /* K */, func_t) -CMC_COLLECTION_GENERATE(TREESET, ts8, tset8, /* K */, func_t) -CMC_COLLECTION_GENERATE(TREEMAP, tm8, tmap8, func_t, func_t) -CMC_COLLECTION_GENERATE(HASHSET, hs8, hset8, /* K */, func_t) -CMC_COLLECTION_GENERATE(HASHMAP, hm8, hmap8, func_t, func_t) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih8, iheap8, /* K */, func_t) -CMC_COLLECTION_GENERATE(MULTIMAP, mm8, mmap8, func_t, func_t) -CMC_COLLECTION_GENERATE(MULTISET, ms8, mset8, /* K */, func_t) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d8, deque8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm8, hashbidimap8, , func_t, func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm8, hashmap8, , func_t, func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm8, hashmultimap8, , func_t, func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms8, hashmultiset8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs8, hashset8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h8, heap8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih8, intervalheap8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll8, linkedlist8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l8, list8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q8, queue8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl8, sortedlist8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s8, stack8, , , func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm8, treemap8, , func_t, func_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts8, treeset8, , , func_t)) -CMC_COLLECTION_GENERATE(LIST, l9, list9, /* K */, func_t) -CMC_COLLECTION_GENERATE(STACK, s9, stack9, /* K */, func_t) -CMC_COLLECTION_GENERATE(QUEUE, q9, queue9, /* K */, func_t) -CMC_COLLECTION_GENERATE(DEQUE, d9, deque9, /* K */, func_t) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll9, linked9, /* K */, func_t) -CMC_COLLECTION_GENERATE(HEAP, h9, heap9, /* K */, func_t) -CMC_COLLECTION_GENERATE(TREESET, ts9, tset9, /* K */, func_t) -CMC_COLLECTION_GENERATE(TREEMAP, tm9, tmap9, func_t, func_t) -CMC_COLLECTION_GENERATE(HASHSET, hs9, hset9, /* K */, func_t) -CMC_COLLECTION_GENERATE(HASHMAP, hm9, hmap9, func_t, func_t) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d9, deque9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm9, hashbidimap9, , func_t *, func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm9, hashmap9, , func_t *, func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm9, hashmultimap9, , func_t *, func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms9, hashmultiset9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs9, hashset9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h9, heap9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih9, intervalheap9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll9, linkedlist9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l9, list9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q9, queue9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl9, sortedlist9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s9, stack9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm9, treemap9, , func_t *, func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts9, treeset9, , , func_t *)) int main(void) { From c16ecd886cd985e0300eec05f37bb55ce32772d9 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 16 Jun 2020 23:43:15 -0300 Subject: [PATCH 37/51] Fixing errors found in types.c tests --- src/cmc/hashmap.h | 4 ++-- src/cmc/hashmultimap.h | 4 ++-- src/cmc/treemap.h | 4 ++-- tests/types.c | 30 +++++++++++++++--------------- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 73d71cd..54ca72c 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -546,7 +546,7 @@ if (CMC_(PFX, _empty)(_map_)) \ { \ _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ + return (V){ 0 }; \ } \ \ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ @@ -569,7 +569,7 @@ if (CMC_(PFX, _empty)(_map_)) \ { \ _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ + return NULL; \ } \ \ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index 16e20b2..51a700a 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -769,7 +769,7 @@ if (CMC_(PFX, _empty)(_map_)) \ { \ _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ + return (V){ 0 }; \ } \ \ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ @@ -792,7 +792,7 @@ if (CMC_(PFX, _empty)(_map_)) \ { \ _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ + return NULL; \ } \ \ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index f3580bf..9f93cfb 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -612,7 +612,7 @@ if (CMC_(PFX, _empty)(_map_)) \ { \ _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ + return (V){ 0 }; \ } \ \ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ @@ -635,7 +635,7 @@ if (CMC_(PFX, _empty)(_map_)) \ { \ _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ + return NULL; \ } \ \ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ diff --git a/tests/types.c b/tests/types.c index 60374e2..9923014 100644 --- a/tests/types.c +++ b/tests/types.c @@ -154,21 +154,21 @@ C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s7, stack7, , , un C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm7, treemap7, , union_t *, union_t *)) C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts7, treeset7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d8, deque8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm8, hashbidimap8, , func_t, func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm8, hashmap8, , func_t, func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm8, hashmultimap8, , func_t, func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms8, hashmultiset8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs8, hashset8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h8, heap8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih8, intervalheap8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll8, linkedlist8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l8, list8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q8, queue8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl8, sortedlist8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s8, stack8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm8, treemap8, , func_t, func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts8, treeset8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d8, deque8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm8, hashbidimap8, , func_t, func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm8, hashmap8, , func_t, func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm8, hashmultimap8, , func_t, func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms8, hashmultiset8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs8, hashset8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h8, heap8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih8, intervalheap8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll8, linkedlist8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l8, list8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q8, queue8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl8, sortedlist8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s8, stack8, , , func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm8, treemap8, , func_t, func_t)) +// C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts8, treeset8, , , func_t)) C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d9, deque9, , , func_t *)) C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm9, hashbidimap9, , func_t *, func_t *)) From f80b17ff82368c84422357f63a4a80b385e1f3ef Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 17 Jun 2020 21:38:00 -0300 Subject: [PATCH 38/51] Updating script and formatting files --- autogen.py | 444 ++++++++++++++++++++++++----------- src/utl/futils.h | 6 +- tests/main.c | 4 +- tests/src/cmc/hashmap.c | 4 +- tests/src/cmc/hashmultimap.c | 4 +- tests/src/cmc/treemap.c | 4 +- tests/types.c | 257 ++++++++++---------- tests/unt/cmc/deque.h | 6 +- tests/unt/cmc/hashmap.h | 6 +- 9 files changed, 451 insertions(+), 284 deletions(-) diff --git a/autogen.py b/autogen.py index 9afc512..833a151 100644 --- a/autogen.py +++ b/autogen.py @@ -1,47 +1,100 @@ # A script that automatically generates code for code coverage, updates tests # and Makefiles, and creates necessary directories +import argparse import os -import sys import re +import shutil import subprocess +import sys +from typing import List, Text -# Make sure we have the specified directory -def assert_dir(dir): - if not os.path.exists(dir): - os.makedirs(dir) +# Config Script Configuration +# Directories Names for directories +# Output Where the outputted code is to be put +# Build Where the build objects are to be located +# Compiler Compiler Configurations +# Compilation Tests, code coverage and flags +# Macro Expansion Configuration for the code expansion +# Collections All collections +# +# Variables marked as const are to not be modified -# Compiler settings +# Directories + +# Output directory +# In this directory it is assumed that the following files and directories are +# included: main.c, unt folder +OUTPUT_DIR = './tests' +# All libraries +ALL_LIBS = ['CMC', 'SAC', 'TSC'] +# Directory mapping +DIR_MAP = {'HEADER': 'include', 'SOURCE': 'src'} +# File extension mapping +EXT_MAP = {'HEADER': 'h', 'SOURCE': 'c'} +# Where compilation objects will be outputted +BUILD_DIR = f'{OUTPUT_DIR}/build' +# const +INCLUDE_DIR = f"{OUTPUT_DIR}/{DIR_MAP['HEADER']}" +# const +SRC_DIR = f"{OUTPUT_DIR}/{DIR_MAP['SOURCE']}" +# Where object files .o go +OBJ_DIR = f'{BUILD_DIR}/obj' +# The name of the main test executable +TEST_EXE = f'{OUTPUT_DIR}/main.exe' + +# Compiler + +# Compilation CC = 'gcc' +# Compilation Flags +CFLAGS = ['-Wall', '-Werror'] +# Coverage Flags +CVFLAGS = ['--coverage', '-O0'] +# Include to the main Library +# const INCLUDE = '-I ./src' +# Include to the test file headers +# const +TINCLUDE = f'-I {INCLUDE_DIR}' + +# Macro expansion + # -E Only preprocessor # -P No linemarkers # -C Keep comments, except those inside macros (for UNIQUE_FLAG) -FLAGS = '-E -P -C' - -# Used to delimiter where the actual code starts and ends -# Used by regex -# Needs to be a valid C comment +# const +EXPAND_FLAGS = '-E -P -C' +# Used to delimiter where the actual code starts and ends. Used by regex. +# Needs to be a valid C comment. UNIQUE_FLAG = '// C_MACRO_COLLECTIONS_CODE' - # Temporary file used to expand the macros TMP_FILE = './main.c' -# Output directory -# In this directory it is assumed that the following files and folders are -# included: main.c, unt folder -OUTPUT_DIR = './tests' +# Just a realy helpfull overview +CONFIG = f'''Directory Settings + OUTPUT_DIR = {OUTPUT_DIR} + ALL_LIBS = {ALL_LIBS} + DIR_MAP = {DIR_MAP} + EXT_MAP = {EXT_MAP} + BUILD_DIR = {BUILD_DIR} + INCLUDE_DIR = {INCLUDE_DIR} + SRC_DIR = {SRC_DIR} + OBJ_DIR = {OBJ_DIR} +Compiler Settings + CC = {CC} + CFLAGS = {CFLAGS} + CVFLAGS = {CVFLAGS} + INCLUDE = {INCLUDE} + TINCLUDE = {TINCLUDE} +Macro Expansion + EXPAND_FLAGS = {EXPAND_FLAGS} + UNIQUE_FLAG = {UNIQUE_FLAG} + TMP_FILE = {TMP_FILE}''' -# All libraries -ALL_LIBS = ['CMC', 'SAC', 'TSC'] -# Directory mapping -DIR_MAP = {'HEADER': 'include', 'SOURCE': 'src'} - -# File extension mapping -EXT_MAP = {'HEADER': 'h', 'SOURCE': 'c'} - -collections = [ +# All collections that can be used for testing +COLLECTIONS = [ # header, library, collection, pfx, sname, size, key, val {'h': '"cmc/bitset.h"', 'LIB': 'CMC', 'COLLECTION': 'BITSET', 'PFX': 'bs', 'SNAME': 'bitset', 'SIZE': '', 'K': '', 'V': '' }, {'h': '"cmc/deque.h"', 'LIB': 'CMC', 'COLLECTION': 'DEQUE', 'PFX': 'd', 'SNAME': 'deque', 'SIZE': '', 'K': '', 'V': 'size_t'}, @@ -61,164 +114,279 @@ collections = [ {'h': '"cmc/treeset.h"', 'LIB': 'CMC', 'COLLECTION': 'TREESET', 'PFX': 'ts', 'SNAME': 'treeset', 'SIZE': '', 'K': '', 'V': 'size_t'} ] -# Create output directory -assert_dir(OUTPUT_DIR) -# include and src -for dir in DIR_MAP.values(): - assert_dir(f'{OUTPUT_DIR}/{dir}') +def execute_command(commands: List[Text]): + print(' '.join(commands)) + subprocess.run(commands, shell=True) -# For each library, create a folder for include and src -for lib in ALL_LIBS: + +def assert_executable(program: Text): + ''' + Asserts that a given program is installed and available in PATH + ''' + if shutil.which(program) is None: + raise Exception(f'The required executable {program} was not found in your path') + + +def assert_dir(dir: Text): + ''' + Given a string 'dir' that is a path to a directory, make sure that it exists. + ''' + if not os.path.exists(dir): + os.makedirs(dir) + + +def assert_structure(): + ''' + Git might not commit some required directories. This function asserts that they exist. + ''' + assert_dir(OUTPUT_DIR) + + # include and src for dir in DIR_MAP.values(): - assert_dir(f'{OUTPUT_DIR}/{dir}/{lib.lower()}') + assert_dir(f'{OUTPUT_DIR}/{dir}') -# Generate Header and Source separately -for ftype in ['HEADER', 'SOURCE']: - for data in collections: - file = open(TMP_FILE, 'w') + # For each library, create a directory for include and src + for lib in ALL_LIBS: + for dir in DIR_MAP.values(): + assert_dir(f'{OUTPUT_DIR}/{dir}/{lib.lower()}') - file.write( - f''' - #include "macro_collections.h" + assert_dir(BUILD_DIR) + assert_dir(OBJ_DIR) - {UNIQUE_FLAG} + for lib in ALL_LIBS: + assert_dir(f'{OBJ_DIR}/{lib.lower()}') - C_MACRO_COLLECTIONS_ALL_{ftype}({data['LIB']}, {data['COLLECTION']}, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) - {UNIQUE_FLAG} - ''') +def clean_build(): + execute_command(['find', BUILD_DIR, '-type', 'f', '-delete']) + execute_command(['find', '.', '-iname', '*.gcov', '-type', 'f', '-delete']) - file.flush() - file.close() - result = subprocess.getoutput(f'{CC} {FLAGS} {INCLUDE} {TMP_FILE}') +def expand_code(): + # Generate Header and Source separately + for ftype in ['HEADER', 'SOURCE']: + for data in COLLECTIONS: + file = open(TMP_FILE, 'w') - # (?s) makes '.' match anything, even '\n' - match = re.search(fr'(?s){UNIQUE_FLAG}(?P.+){UNIQUE_FLAG}', result) - - if match is None: - os.remove(TMP_FILE) - print('Didn\'t match FLAG. Probably because compilation failed.', file=sys.stderr) - exit(1) - - file = open(f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}', 'w') - - if ftype == 'HEADER': file.write( f''' - #ifndef CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H - #define CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H - #include "macro_collections.h" - {match.group('code')} - #endif /* CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H */ - ''') - else: - file.write( - f''' - #include {data["h"]} + {UNIQUE_FLAG} - {match.group("code")} + C_MACRO_COLLECTIONS_ALL_{ftype}({data['LIB']}, {data['COLLECTION']}, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) + + {UNIQUE_FLAG} ''') - file.flush() - file.close() + file.flush() + file.close() - print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}') + result = subprocess.getoutput(f'{CC} {EXPAND_FLAGS} {INCLUDE} {TMP_FILE}') -os.remove(TMP_FILE) + # (?s) makes '.' match anything, even '\n' + match = re.search(fr'(?s){UNIQUE_FLAG}(?P.+){UNIQUE_FLAG}', result) -# Format all files -from shutil import which + if match is None: + os.remove(TMP_FILE) + print('Didn\'t match FLAG. Probably because compilation failed.', file=sys.stderr) + exit(1) -if which('clang-format') is not None: - print('clang-format found. Formating files...') + file = open(f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}', 'w') + if ftype == 'HEADER': + file.write( + f''' + #ifndef CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H + #define CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H + + #include "macro_collections.h" + {match.group('code')} + + #endif /* CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H */ + ''') + else: + file.write( + f''' + #include {data["h"]} + + {match.group("code")} + ''') + + file.flush() + file.close() + + print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}') + + os.remove(TMP_FILE) + + +def format_expand(): cmd = ['clang-format', '--style=file', '--verbose', '-i'] dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{lib.lower()}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys() for lib in ALL_LIBS] - cmd.extend(dirs_to_format) - subprocess.call(cmd) -else: - print('clang-format not found. Skipping code formatting...') + execute_command(cmd) -# Makefile -# Contains many usefull things dealing with tests, code coverage and formatting -BUILD_DIR = f'{OUTPUT_DIR}/build' -OBJ_DIR = f'{BUILD_DIR}/obj' -INCLUDE_DIR = f"{OUTPUT_DIR}/{DIR_MAP['HEADER']}" -SRC_DIR = f"{OUTPUT_DIR}/{DIR_MAP['SOURCE']}" -assert_dir(BUILD_DIR) -assert_dir(OBJ_DIR) +def format_code(source: bool, tests: bool): + if source: + execute_command(['find', './src/', '-iname', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) + if tests: + execute_command(['find', './tests/', '-iname', '*.c', '-o', '-iname', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) -for lib in ALL_LIBS: - assert_dir(f'{OBJ_DIR}/{lib.lower()}') -print('Updating Makefile...') +def build_tests(with_coverage: bool): + cflags = CFLAGS.copy() -file = open(f'Makefile', 'w') + if with_coverage: + cflags += CVFLAGS -file.write(f'''# This file was generated by a Python script -CC = {CC} -CFLAGS = -std=c11 -Wall -Wextra -CFLAGS += -Wno-missing-braces -DCMC_TEST_COLOR -CVFLAGS = --coverage -O0 -g3 -INCLUDE = {INCLUDE_DIR} -I src + print("WIP") -# Runs the script to update tests, run all tests and code coverage -all: script coverage -tests: script build -\t{OUTPUT_DIR}/main.exe +def run_tests(): + execute_command([TEST_EXE]) -# Like build but with coverage -coverage: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in collections])} {OBJ_DIR}/main.o -\t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) $(CVFLAGS) -\t{OUTPUT_DIR}/main.exe -\tgcov {OBJ_DIR}/main.o {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in collections])} -# Run without coverage -run: build -\t{OUTPUT_DIR}/main.exe +def unused(): + # Makefile + # Contains many usefull things dealing with tests, code coverage and formatting -script: -\tpython autogen.py + print('Updating Makefile...') -clean: -\tfind {BUILD_DIR} -type f -delete -\trm *.gcov + file = open(f'Makefile', 'w') -# No coverage build -build: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in collections])} {OBJ_DIR}/main.o -\t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) + file.write(f'''# This file was generated by a Python script + CC = {CC} + CFLAGS = -std=c11 -Wall -Wextra + CFLAGS += -Wno-missing-braces -DCMC_TEST_COLOR + CVFLAGS = --coverage -O0 -g3 + INCLUDE = {INCLUDE_DIR} -I src -{OBJ_DIR}/main.o: {OUTPUT_DIR}/main.c -\t$(CC) -c $^ -o $@ -I $(INCLUDE) $(CFLAGS) -''') + # Runs the script to update tests, run all tests and code coverage + all: script coverage -# Code formatting -file.write(''' -fmt_all: fmt_src fmt_tests + tests: script build + \t{OUTPUT_DIR}/main.exe -fmt_src: FORCE - find ./src/ -iname *.h | xargs clang-format --style=file --verbose -i + # Like build but with coverage + coverage: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])} {OBJ_DIR}/main.o + \t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) $(CVFLAGS) + \t{OUTPUT_DIR}/main.exe + \tgcov {OBJ_DIR}/main.o {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])} -fmt_tests: FORCE - find ./tests/ -iname *.c -o -iname *.h | xargs clang-format --style=file --verbose -i + # Run without coverage + run: build + \t{OUTPUT_DIR}/main.exe -.PHONY FORCE: + script: + \tpython autogen.py -''') + clean: + \tfind {BUILD_DIR} -type f -delete + \trm *.gcov -for data in collections: - file.write(f''' -{OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o: {SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c {INCLUDE_DIR}/{data['LIB'].lower()}/{data['SNAME']}.h -\t$(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) -''') + # No coverage build + build: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])} {OBJ_DIR}/main.o + \t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) -file.close() + {OBJ_DIR}/main.o: {OUTPUT_DIR}/main.c + \t$(CC) -c $^ -o $@ -I $(INCLUDE) $(CFLAGS) + ''') -print('\nDone') + for data in COLLECTIONS: + file.write(f''' + {OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o: {SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c {INCLUDE_DIR}/{data['LIB'].lower()}/{data['SNAME']}.h + \t$(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) + ''') + + file.close() + print('\nDone') + + +if __name__ == '__main__': + p = argparse.ArgumentParser('autogen.py', usage='%(prog)s [options]') + + p.add_argument('-sc', '--show-config', + help='Displays the current configuration', + action='store_true', + dest='config') + + tests = p.add_argument_group('tests', 'For dealing with tests') + + tests.add_argument('-c', '--clean', + help='Cleans all build objects', + default=False, + action='store_true', + dest='clean') + tests.add_argument('-e', '--expand', + help='Expands the header and source files', + default=False, + action='store_true', + dest='expand') + tests.add_argument('-nf', '--no-format', + help='Does not format the output of expand. Can be used when you might not have clang-format', + default=False, + action='store_true', + dest='noformat') + tests.add_argument('-r', '--run', + help='Runs tests without code coverage', + default=False, + action='store_true', + dest='run') + tests.add_argument('-cv', '--coverage', + help='Compiles and runs tests with code coverage', + default=False, + action='store_true', + dest='coverage') + tests.add_argument('-rr', '--rerun', + help='Builds tests without code coverage and runs it', + default=False, + action='store_true', + dest='rerun') + + source = p.add_argument_group('source', 'For dealing with the source files and formatting') + + source.add_argument('-fs', '--format-source', + help='Format the source code', + default=False, + action='store_true', + dest='fmt_source') + source.add_argument('-ft', '--format-tests', + help='Format tests files', + default=False, + action='store_true', + dest='fmt_tests') + + args = p.parse_args() + + if args.config: + print(CONFIG) + exit(0) + + if args.clean: + clean_build() + + assert_structure() + assert_executable(CC) + + if args.expand: + expand_code() + if not args.noformat: + assert_executable('clang-format') + format_expand() + + if args.fmt_source or args.fmt_tests: + assert_executable('find') + assert_executable('xargs') + format_code(args.fmt_source, args.fmt_tests) + + if args.rerun: + build_tests(False) + run_tests() + elif args.run: + run_tests() + elif args.coverage: + build_tests(True) + run_tests() diff --git a/src/utl/futils.h b/src/utl/futils.h index 28f9473..26726dc 100644 --- a/src/utl/futils.h +++ b/src/utl/futils.h @@ -323,7 +323,8 @@ static inline size_t cmc_float_hash(float e) if (e == 0.0) e = 0.0; // if e == -0.0, now it is 0.0 - union { + union + { float a; size_t b; } x; @@ -342,7 +343,8 @@ static inline size_t cmc_double_hash(double e) if (e == 0.0) e = 0.0; // if e == -0.0, now it is 0.0 - union { + union + { double a; size_t b; } x; diff --git a/tests/main.c b/tests/main.c index 51de592..4007f43 100644 --- a/tests/main.c +++ b/tests/main.c @@ -1,5 +1,5 @@ -#include #include +#include #include "unt/cmc/bitset.h" #include "unt/cmc/deque.h" @@ -20,8 +20,8 @@ #include "unt/utl/foreach.h" -#include "utl/timer.h" #include "utl/assert.h" +#include "utl/timer.h" #include "./unt/utl.h" diff --git a/tests/src/cmc/hashmap.c b/tests/src/cmc/hashmap.c index 8d49630..7fb16b5 100644 --- a/tests/src/cmc/hashmap.c +++ b/tests/src/cmc/hashmap.c @@ -277,7 +277,7 @@ size_t hm_get(struct hashmap *_map_, size_t key) if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; - return 0; + return (size_t){ 0 }; } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) @@ -296,7 +296,7 @@ size_t *hm_get_ref(struct hashmap *_map_, size_t key) if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; - return 0; + return ((void *)0); } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) diff --git a/tests/src/cmc/hashmultimap.c b/tests/src/cmc/hashmultimap.c index 7450bee..45ef628 100644 --- a/tests/src/cmc/hashmultimap.c +++ b/tests/src/cmc/hashmultimap.c @@ -423,7 +423,7 @@ size_t hmm_get(struct hashmultimap *_map_, size_t key) if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; - return 0; + return (size_t){ 0 }; } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) @@ -442,7 +442,7 @@ size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; - return 0; + return ((void *)0); } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) diff --git a/tests/src/cmc/treemap.c b/tests/src/cmc/treemap.c index 39ceb86..6c495e7 100644 --- a/tests/src/cmc/treemap.c +++ b/tests/src/cmc/treemap.c @@ -339,7 +339,7 @@ size_t tm_get(struct treemap *_map_, size_t key) if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; - return 0; + return (size_t){ 0 }; } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) @@ -358,7 +358,7 @@ size_t *tm_get_ref(struct treemap *_map_, size_t key) if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; - return 0; + return ((void *)0); } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) diff --git a/tests/types.c b/tests/types.c index 9923014..ec6678f 100644 --- a/tests/types.c +++ b/tests/types.c @@ -17,142 +17,143 @@ typedef enum enum_e NONE = 0 } enum_t; -typedef union union_u { +typedef union union_u +{ enum enum_e a; struct struct_s b; double c; char *d; } union_t; -typedef int (func_t)(int, double, char *); +typedef int(func_t)(int, double, char *); -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d0, deque0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm0, hashbidimap0, , struct_t *, struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm0, hashmap0, , struct_t *, struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d0, deque0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm0, hashbidimap0, , struct_t *, struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm0, hashmap0, , struct_t *, struct_t *)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm0, hashmultimap0, , struct_t *, struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms0, hashmultiset0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs0, hashset0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h0, heap0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih0, intervalheap0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll0, linkedlist0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l0, list0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q0, queue0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl0, sortedlist0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s0, stack0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm0, treemap0, , struct_t *, struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts0, treeset0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms0, hashmultiset0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs0, hashset0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h0, heap0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih0, intervalheap0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll0, linkedlist0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l0, list0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q0, queue0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl0, sortedlist0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s0, stack0, , , struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm0, treemap0, , struct_t *, struct_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts0, treeset0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d1, deque1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm1, hashbidimap1, , struct_t, struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm1, hashmap1, , struct_t, struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d1, deque1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm1, hashbidimap1, , struct_t, struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm1, hashmap1, , struct_t, struct_t)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm1, hashmultimap1, , struct_t, struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms1, hashmultiset1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs1, hashset1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h1, heap1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih1, intervalheap1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll1, linkedlist1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l1, list1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q1, queue1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl1, sortedlist1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s1, stack1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm1, treemap1, , struct_t, struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts1, treeset1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms1, hashmultiset1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs1, hashset1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h1, heap1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih1, intervalheap1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll1, linkedlist1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l1, list1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q1, queue1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl1, sortedlist1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s1, stack1, , , struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm1, treemap1, , struct_t, struct_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts1, treeset1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d2, deque2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm2, hashbidimap2, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm2, hashmap2, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d2, deque2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm2, hashbidimap2, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm2, hashmap2, , int, int)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm2, hashmultimap2, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms2, hashmultiset2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs2, hashset2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h2, heap2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih2, intervalheap2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll2, linkedlist2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l2, list2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q2, queue2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl2, sortedlist2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s2, stack2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm2, treemap2, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts2, treeset2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms2, hashmultiset2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs2, hashset2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h2, heap2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih2, intervalheap2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll2, linkedlist2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l2, list2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q2, queue2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl2, sortedlist2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s2, stack2, , , int)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm2, treemap2, , int, int)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts2, treeset2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d3, deque3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm3, hashbidimap3, , int *, int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm3, hashmap3, , int *, int *)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d3, deque3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm3, hashbidimap3, , int *, int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm3, hashmap3, , int *, int *)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm3, hashmultimap3, , int *, int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms3, hashmultiset3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs3, hashset3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h3, heap3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih3, intervalheap3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll3, linkedlist3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l3, list3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q3, queue3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl3, sortedlist3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s3, stack3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm3, treemap3, , int *, int *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts3, treeset3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms3, hashmultiset3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs3, hashset3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h3, heap3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih3, intervalheap3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll3, linkedlist3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l3, list3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q3, queue3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl3, sortedlist3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s3, stack3, , , int *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm3, treemap3, , int *, int *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts3, treeset3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d4, deque4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm4, hashbidimap4, , enum_t, enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm4, hashmap4, , enum_t, enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d4, deque4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm4, hashbidimap4, , enum_t, enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm4, hashmap4, , enum_t, enum_t)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm4, hashmultimap4, , enum_t, enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms4, hashmultiset4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs4, hashset4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h4, heap4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih4, intervalheap4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll4, linkedlist4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l4, list4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q4, queue4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl4, sortedlist4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s4, stack4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm4, treemap4, , enum_t, enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts4, treeset4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms4, hashmultiset4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs4, hashset4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h4, heap4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih4, intervalheap4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll4, linkedlist4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l4, list4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q4, queue4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl4, sortedlist4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s4, stack4, , , enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm4, treemap4, , enum_t, enum_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts4, treeset4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d5, deque5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm5, hashbidimap5, , enum_t *, enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm5, hashmap5, , enum_t *, enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d5, deque5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm5, hashbidimap5, , enum_t *, enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm5, hashmap5, , enum_t *, enum_t *)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm5, hashmultimap5, , enum_t *, enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms5, hashmultiset5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs5, hashset5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h5, heap5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih5, intervalheap5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll5, linkedlist5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l5, list5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q5, queue5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl5, sortedlist5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s5, stack5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm5, treemap5, , enum_t *, enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts5, treeset5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms5, hashmultiset5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs5, hashset5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h5, heap5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih5, intervalheap5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll5, linkedlist5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l5, list5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q5, queue5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl5, sortedlist5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s5, stack5, , , enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm5, treemap5, , enum_t *, enum_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts5, treeset5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d6, deque6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm6, hashbidimap6, , union_t, union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm6, hashmap6, , union_t, union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d6, deque6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm6, hashbidimap6, , union_t, union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm6, hashmap6, , union_t, union_t)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm6, hashmultimap6, , union_t, union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms6, hashmultiset6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs6, hashset6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h6, heap6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih6, intervalheap6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll6, linkedlist6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l6, list6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q6, queue6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl6, sortedlist6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s6, stack6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm6, treemap6, , union_t, union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts6, treeset6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms6, hashmultiset6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs6, hashset6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h6, heap6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih6, intervalheap6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll6, linkedlist6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l6, list6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q6, queue6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl6, sortedlist6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s6, stack6, , , union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm6, treemap6, , union_t, union_t)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts6, treeset6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d7, deque7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm7, hashbidimap7, , union_t *, union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm7, hashmap7, , union_t *, union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d7, deque7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm7, hashbidimap7, , union_t *, union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm7, hashmap7, , union_t *, union_t *)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm7, hashmultimap7, , union_t *, union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms7, hashmultiset7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs7, hashset7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h7, heap7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih7, intervalheap7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll7, linkedlist7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l7, list7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q7, queue7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl7, sortedlist7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s7, stack7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm7, treemap7, , union_t *, union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts7, treeset7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms7, hashmultiset7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs7, hashset7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h7, heap7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih7, intervalheap7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll7, linkedlist7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l7, list7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q7, queue7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl7, sortedlist7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s7, stack7, , , union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm7, treemap7, , union_t *, union_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts7, treeset7, , , union_t *)) // C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d8, deque8, , , func_t)) // C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm8, hashbidimap8, , func_t, func_t)) @@ -170,21 +171,21 @@ C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts7, treeset7, , , un // C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm8, treemap8, , func_t, func_t)) // C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts8, treeset8, , , func_t)) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d9, deque9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm9, hashbidimap9, , func_t *, func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm9, hashmap9, , func_t *, func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d9, deque9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm9, hashbidimap9, , func_t *, func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm9, hashmap9, , func_t *, func_t *)) C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm9, hashmultimap9, , func_t *, func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms9, hashmultiset9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs9, hashset9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h9, heap9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih9, intervalheap9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll9, linkedlist9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l9, list9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q9, queue9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl9, sortedlist9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s9, stack9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm9, treemap9, , func_t *, func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts9, treeset9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms9, hashmultiset9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs9, hashset9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h9, heap9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih9, intervalheap9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll9, linkedlist9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l9, list9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q9, queue9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl9, sortedlist9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s9, stack9, , , func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm9, treemap9, , func_t *, func_t *)) +C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts9, treeset9, , , func_t *)) int main(void) { diff --git a/tests/unt/cmc/deque.h b/tests/unt/cmc/deque.h index af4fb8e..a072906 100644 --- a/tests/unt/cmc/deque.h +++ b/tests/unt/cmc/deque.h @@ -110,8 +110,7 @@ CMC_CREATE_UNIT(CMCDeque, true, { }); CMC_CREATE_TEST(PFX##_init_custom(), { - struct deque d = - d_init_custom(1000000, d_fval, d_alloc_node, callbacks); + struct deque d = d_init_custom(1000000, d_fval, d_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, d.buffer); cmc_assert_equals(size_t, 1000000, d.capacity); @@ -247,8 +246,7 @@ CMC_CREATE_UNIT(CMCDeque, true, { cmc_assert_equals(size_t, 1000, d_count(&d)); size_t sum = 0; - for (size_t i = d.front, j = 0; j < d.count; - i = (i + 1) % d.capacity, j++) + for (size_t i = d.front, j = 0; j < d.count; i = (i + 1) % d.capacity, j++) sum += d.buffer[i]; cmc_assert_equals(size_t, 500500, sum); diff --git a/tests/unt/cmc/hashmap.h b/tests/unt/cmc/hashmap.h index a0710a2..c255fa8 100644 --- a/tests/unt/cmc/hashmap.h +++ b/tests/unt/cmc/hashmap.h @@ -130,8 +130,7 @@ CMC_CREATE_UNIT(CMCHashMap, true, { }); CMC_CREATE_TEST(PFX##_init_custom(), { - struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, - hm_alloc_node, callbacks); + struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, hm_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, map.buffer); cmc_assert_equals(size_t, 0, map.count); @@ -227,8 +226,7 @@ CMC_CREATE_UNIT(CMCHashMap, true, { CMC_CREATE_TEST(PFX##_release(), { k_total_free = 0; v_total_free = 0; - struct hashmap map = - hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter); + struct hashmap map = hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter); cmc_assert_not_equals(ptr, NULL, map.buffer); From 66b6677afae2815c320a8cbc4e77e4a241d84c4e Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 19 Jun 2020 19:38:55 -0300 Subject: [PATCH 39/51] Quick fix --- src/cmc/queue.h | 19 ------------------- src/ext/cmc/queue.h | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cmc/queue.h b/src/cmc/queue.h index 3e47e99..acb73c3 100644 --- a/src/cmc/queue.h +++ b/src/cmc/queue.h @@ -144,25 +144,6 @@ /* Priority function */ \ CMC_DEF_FTAB_PRI(V); \ }; \ -\ - /* Queue Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target queue */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ diff --git a/src/ext/cmc/queue.h b/src/ext/cmc/queue.h index 655e895..23a0e53 100644 --- a/src/ext/cmc/queue.h +++ b/src/ext/cmc/queue.h @@ -32,6 +32,25 @@ CMC_EXT_CMC_QUEUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_QUEUE_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* Queue Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target queue */ \ + struct SNAME *target; \ +\ + /* Cursor's position (index) */ \ + size_t cursor; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ \ /* Iterator Initialization */ \ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ From feaac16804fe93ce0d6b26f71694b6c32f638d74 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 19 Jun 2020 22:37:25 -0300 Subject: [PATCH 40/51] Update benchmark --- benchmarks/C++ Comparison/hashtable/hashmap.c | 48 +++++++++----- .../C++ Comparison/hashtable/hashmultimap.c | 61 ++++++++++++++++++ .../C++ Comparison/hashtable/murmurhash.h | 58 +++++++++++++++++ benchmarks/C++ Comparison/hashtable/script.py | 63 +++++++++---------- .../C++ Comparison/hashtable/unorderedmap.cpp | 26 ++++++-- 5 files changed, 204 insertions(+), 52 deletions(-) create mode 100644 benchmarks/C++ Comparison/hashtable/hashmultimap.c create mode 100644 benchmarks/C++ Comparison/hashtable/murmurhash.h diff --git a/benchmarks/C++ Comparison/hashtable/hashmap.c b/benchmarks/C++ Comparison/hashtable/hashmap.c index d2c4dbe..5956b8b 100644 --- a/benchmarks/C++ Comparison/hashtable/hashmap.c +++ b/benchmarks/C++ Comparison/hashtable/hashmap.c @@ -2,32 +2,42 @@ #error "Please define COUNT" #endif -#include "cmc/hashmap.h" +#include "murmurhash.h" -CMC_CMC_HASHMAP_CORE(PUBLIC, HEADER, (hmi32, hashmapi32, , int32_t, int32_t)) -CMC_CMC_HASHMAP_CORE(PUBLIC, SOURCE, (hmi32, hashmapi32, , int32_t, int32_t)) +#include "macro_collections.h" -int cmp(int32_t a, int32_t b) +#include "../../util/twister.c" + +CMC_CMC_HASHMAP_CORE(PUBLIC, HEADER, (hm, hashmap, , uint64_t, uint64_t)) +CMC_CMC_HASHMAP_CORE(PUBLIC, SOURCE, (hm, hashmap, , uint64_t, uint64_t)) + +int cmp(uint64_t a, uint64_t b) { return (a > b) - (a < b); } -size_t hash(int32_t a) +// size_t hash(uint64_t a) +// { +// size_t x = (size_t)a; +// x = ((x >> 16) ^ x) * 0x45d9f3b; +// x = ((x >> 16) ^ x) * 0x45d9f3b; +// x = (x >> 16) ^ x; +// return x; +// } + +size_t hash(uint64_t k) { - size_t x = (size_t)a; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = (x >> 16) ^ x; - return x; + static size_t seed = 211106232532969; + return MurMurHash(&k, sizeof(k), seed); } -struct hashmapi32_fkey *fkey = &(struct hashmapi32_fkey) { +struct hashmap_fkey *fkey = &(struct hashmap_fkey) { .cmp = cmp, .hash = hash, NULL }; -struct hashmapi32_fval *fval = &(struct hashmapi32_fval) { +struct hashmap_fval *fval = &(struct hashmap_fval) { .cmp = cmp, .hash = hash, NULL @@ -35,12 +45,18 @@ struct hashmapi32_fval *fval = &(struct hashmapi32_fval) { int main(void) { - struct hashmapi32 *map = hmi32_new(COUNT, 0.6, fkey, fval); + mt_state tw; + twist_init(&tw, 50331653); - for (int32_t i = 0; i < COUNT; i++) - hmi32_insert(map, i, i); + struct hashmap *map = hm_new(COUNT, 0.6, fkey, fval); - hmi32_free(map); + for (uint64_t i = 0; i < COUNT; i++) + { + uint64_t v = twist_uint64(&tw); + hm_insert(map, v, v); + } + + hm_free(map); return 0; } diff --git a/benchmarks/C++ Comparison/hashtable/hashmultimap.c b/benchmarks/C++ Comparison/hashtable/hashmultimap.c new file mode 100644 index 0000000..2bac19a --- /dev/null +++ b/benchmarks/C++ Comparison/hashtable/hashmultimap.c @@ -0,0 +1,61 @@ +#ifndef COUNT +#error "Please define COUNT" +#endif + +#include "murmurhash.h" + +#include "macro_collections.h" + +#include "../../util/twister.c" + +C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , uint64_t, uint64_t)) + +int cmp(uint64_t a, uint64_t b) +{ + return (a > b) - (a < b); +} + +// size_t hash(uint64_t a) +// { +// size_t x = (size_t)a; +// x = ((x >> 16) ^ x) * 0x45d9f3b; +// x = ((x >> 16) ^ x) * 0x45d9f3b; +// x = (x >> 16) ^ x; +// return x; +// } + +size_t hash(uint64_t k) +{ + static size_t seed = 211106232532969; + return MurMurHash(&k, sizeof(k), seed); +} + +struct hashmultimap_fkey *fkey = &(struct hashmultimap_fkey) { + .cmp = cmp, + .hash = hash, + NULL +}; + +struct hashmultimap_fval *fval = &(struct hashmultimap_fval) { + .cmp = cmp, + .hash = hash, + NULL +}; + +int main(void) +{ + mt_state tw; + twist_init(&tw, 50331653); + + struct hashmultimap *map = hmm_new(COUNT, 0.6, fkey, fval); + + for (uint64_t i = 0; i < COUNT; i++) + { + uint64_t v = twist_uint64(&tw); + hmm_insert(map, v, v); + } + + hmm_free(map); + + return 0; +} diff --git a/benchmarks/C++ Comparison/hashtable/murmurhash.h b/benchmarks/C++ Comparison/hashtable/murmurhash.h new file mode 100644 index 0000000..a334dd9 --- /dev/null +++ b/benchmarks/C++ Comparison/hashtable/murmurhash.h @@ -0,0 +1,58 @@ +// https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/hash_bytes.cc + +#ifndef MURMURHASH +#define MURMURHASH + +#include + +inline size_t unaligned_load(const char *p) +{ + size_t result; + memcpy(&result, p, sizeof(result)); + return result; +} + +inline size_t load_bytes(const char *p, int n) +{ + size_t result = 0; + --n; + do + { + result = (result << 8) + (unsigned char)(p[n]); + } while (--n >= 0); + return result; +} + +inline size_t shift_mix(size_t v) +{ + return v ^ (v >> 47); +} + +size_t MurMurHash(const void *ptr, size_t len, size_t seed) +{ + static const size_t mul = (((size_t)0xc6a4a793UL) << 32UL) + (size_t)0x5bd1e995UL; + const char *const buf = (const char *)(ptr); + + // Remove the bytes not divisible by the sizeof(size_t). This + // allows the main loop to process the data as 64-bit integers. + const size_t len_aligned = len & ~(size_t)0x7; + const char *const end = buf + len_aligned; + size_t hash = seed ^ (len * mul); + for (const char *p = buf; p != end; p += 8) + { + const size_t data = shift_mix(unaligned_load(p) * mul) * mul; + hash ^= data; + hash *= mul; + } + if ((len & 0x7) != 0) + { + const size_t data = load_bytes(end, len & 0x7); + hash ^= data; + hash *= mul; + } + hash = shift_mix(hash) * mul; + hash = shift_mix(hash); + return hash; +} + +#endif /* MURMURHASH */ diff --git a/benchmarks/C++ Comparison/hashtable/script.py b/benchmarks/C++ Comparison/hashtable/script.py index bcda9fb..bd939ec 100644 --- a/benchmarks/C++ Comparison/hashtable/script.py +++ b/benchmarks/C++ Comparison/hashtable/script.py @@ -1,8 +1,10 @@ +import os import sys import time import subprocess ITERATIONS = 10 +COUNT = 20000000 VERBOSE = False NL = '\n' @@ -11,48 +13,45 @@ INCLUDE = "../../../src" CC = 'gcc' CCPP = 'g++' # LoL OPT = '-O3' -COUNT = 2000000 + +print(f'Using {CC} compiler') + + +def execute_command(commands): + print(' '.join(commands)) + subprocess.run(commands, shell=True) + # Common args args = ['-I', INCLUDE, OPT, f'-DCOUNT={COUNT}', '-DCMC_NO_CALLBACKS'] -c_args = [CC, 'hashmap.c', '-o', 'hashmap.exe'] +map_args = [CC, 'hashmap.c', '-o', 'hashmap.exe'] +mmap_args = [CC, 'hashmultimap.c', '-o', 'hashmultimap.exe'] cpp_args = [CCPP, 'unorderedmap.cpp', '-I', INCLUDE, '-o', 'unorderedmap.exe', OPT, f'-DCOUNT={COUNT}'] -c_args.extend(args) +map_args.extend(args) +mmap_args.extend(args) cpp_args.extend(args) -subprocess.check_output(c_args) -subprocess.check_output(cpp_args) +execute_command(map_args) +execute_command(mmap_args) +execute_command(cpp_args) -total = 0 -for i in range(ITERATIONS): - print(f'{i}...', end='') - sys.stdout.flush() - start_time = time.time() - subprocess.call(['./hashmap.exe']) +programs = ['hashmap.exe', 'hashmultimap.exe', 'unorderedmap.exe'] - delta = time.time() - start_time - total += delta +for prog in programs: + total = 0 + for i in range(ITERATIONS): + print(f'{i}...', end='') + sys.stdout.flush() + start_time = time.time() + subprocess.run(prog, shell=True) - if VERBOSE: - print(f'({delta})') + delta = time.time() - start_time + total += delta -avg = int(((total / ITERATIONS) * 1e9) / COUNT) -print(f'{"" if VERBOSE else NL}{total / ITERATIONS} seconds for {COUNT} -> AVG[{avg} ns] [hashmap.exe]{NL if VERBOSE else ""}') + if VERBOSE: + print(f'({delta})') -total = 0 -for i in range(ITERATIONS): - print(f'{i}...', end='') - sys.stdout.flush() - start_time = time.time() - subprocess.call(['./unorderedmap.exe']) - - delta = time.time() - start_time - total += delta - - if VERBOSE: - print(f'({delta})') - -avg = int(((total / ITERATIONS) * 1e9) / COUNT) -print(f'{"" if VERBOSE else NL}{total / ITERATIONS} seconds for {COUNT} -> AVG[{avg} ns] [unorderedmap.exe]{NL if VERBOSE else ""}') + avg = total / ITERATIONS + print(f'{"" if VERBOSE else NL}{avg} seconds for {COUNT} -> AVG[{int((avg * 1e9) / COUNT)} ns] [{prog}]{NL if VERBOSE else ""}') diff --git a/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp b/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp index 72cbf0b..5f59f00 100644 --- a/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp +++ b/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp @@ -2,15 +2,33 @@ #error "Please define COUNT" #endif +#include "murmurhash.h" + #include -#include + +#include "../../util/twister.c" + +struct IntHasher +{ + std::size_t operator()(const uint64_t& k) const + { + static size_t seed = 211106232532969; + return MurMurHash(&k, sizeof(k), seed); + } +}; int main(void) { - std::unordered_map map(COUNT); + mt_state tw; + twist_init(&tw, 50331653); - for (int32_t i = 0; i < COUNT; i++) - map.insert({i, i}); + std::unordered_map map(COUNT); + + for (uint64_t i = 0; i < COUNT; i++) + { + uint64_t v = twist_uint64(&tw); + map.insert({v, v}); + } return 0; } From a1e0a4edbb27676c4a5d4a4ca19631a6abfc74fe Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sat, 20 Jun 2020 12:12:47 -0300 Subject: [PATCH 41/51] Updating autogen script --- .travis.yml | 2 +- autogen.py | 204 +++++++++++++++++++---------------- src/cmc/hashmap.h | 8 +- src/cmc/hashmultimap.h | 8 +- src/cmc/hashmultiset.h | 4 +- src/cmc/hashset.h | 20 ++-- tests/include/cmc/queue.h | 16 +-- tests/src/cmc/hashmap.c | 8 +- tests/src/cmc/hashmultimap.c | 8 +- tests/src/cmc/hashmultiset.c | 4 +- tests/src/cmc/hashset.c | 20 ++-- 11 files changed, 161 insertions(+), 141 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7a47c6d..13ec3b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,6 @@ script: - export CC=gcc-9 - gcc --version - python --version - - make + - python autogen.py -e -b -cv -r after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/autogen.py b/autogen.py index 833a151..b5b2644 100644 --- a/autogen.py +++ b/autogen.py @@ -3,6 +3,7 @@ import argparse import os +import pathlib import re import shutil import subprocess @@ -39,7 +40,7 @@ INCLUDE_DIR = f"{OUTPUT_DIR}/{DIR_MAP['HEADER']}" # const SRC_DIR = f"{OUTPUT_DIR}/{DIR_MAP['SOURCE']}" # Where object files .o go -OBJ_DIR = f'{BUILD_DIR}/obj' +OBJ_DIR = BUILD_DIR # The name of the main test executable TEST_EXE = f'{OUTPUT_DIR}/main.exe' @@ -53,10 +54,10 @@ CFLAGS = ['-Wall', '-Werror'] CVFLAGS = ['--coverage', '-O0'] # Include to the main Library # const -INCLUDE = '-I ./src' +INCLUDE = ['-I', './src'] # Include to the test file headers # const -TINCLUDE = f'-I {INCLUDE_DIR}' +TINCLUDE = ['-I', f'{INCLUDE_DIR}'] # Macro expansion @@ -115,25 +116,36 @@ COLLECTIONS = [ ] +def full_path(path: Text) -> Text: + ''' + Returns the full path of a 'path' with ralative paths, e.g. './' or '../' + ''' + return str(pathlib.Path(path).resolve()) + + def execute_command(commands: List[Text]): print(' '.join(commands)) - subprocess.run(commands, shell=True) + cp = subprocess.run(commands, shell=True) + + # if cp.returncode != 0: + # print('Error when executing the last command') + # exit(1) def assert_executable(program: Text): ''' - Asserts that a given program is installed and available in PATH + Asserts that a given program is installed and available in PATH. ''' if shutil.which(program) is None: raise Exception(f'The required executable {program} was not found in your path') -def assert_dir(dir: Text): +def assert_dir(directory: Text): ''' - Given a string 'dir' that is a path to a directory, make sure that it exists. + Given a string 'directory' that is a path to a directory, make sure that it exists. ''' - if not os.path.exists(dir): - os.makedirs(dir) + if not os.path.exists(directory): + os.makedirs(directory) def assert_structure(): @@ -143,13 +155,13 @@ def assert_structure(): assert_dir(OUTPUT_DIR) # include and src - for dir in DIR_MAP.values(): - assert_dir(f'{OUTPUT_DIR}/{dir}') + for directory in DIR_MAP.values(): + assert_dir(f'{OUTPUT_DIR}/{directory}') # For each library, create a directory for include and src for lib in ALL_LIBS: - for dir in DIR_MAP.values(): - assert_dir(f'{OUTPUT_DIR}/{dir}/{lib.lower()}') + for directory in DIR_MAP.values(): + assert_dir(f'{OUTPUT_DIR}/{directory}/{lib.lower()}') assert_dir(BUILD_DIR) assert_dir(OBJ_DIR) @@ -158,12 +170,21 @@ def assert_structure(): assert_dir(f'{OBJ_DIR}/{lib.lower()}') -def clean_build(): - execute_command(['find', BUILD_DIR, '-type', 'f', '-delete']) - execute_command(['find', '.', '-iname', '*.gcov', '-type', 'f', '-delete']) +def clean_build(cleanfull: bool): + ''' + Removes all files generated by compilation and code coverage along with folders. + ''' + execute_command(['rm', '-r', '*.gcov']) + execute_command(['rm', TEST_EXE]) + + for directory in [BUILD_DIR, SRC_DIR, INCLUDE_DIR]: + execute_command(['rm', '-r', directory]) def expand_code(): + ''' + Expands code to be used in tests. This is necessary because code coverage doesn't work with macros. + ''' # Generate Header and Source separately for ftype in ['HEADER', 'SOURCE']: for data in COLLECTIONS: @@ -183,7 +204,7 @@ def expand_code(): file.flush() file.close() - result = subprocess.getoutput(f'{CC} {EXPAND_FLAGS} {INCLUDE} {TMP_FILE}') + result = subprocess.getoutput(f'{CC} {EXPAND_FLAGS} {" ".join(INCLUDE)} {TMP_FILE}') # (?s) makes '.' match anything, even '\n' match = re.search(fr'(?s){UNIQUE_FLAG}(?P.+){UNIQUE_FLAG}', result) @@ -223,6 +244,9 @@ def expand_code(): def format_expand(): + ''' + Format the files outputted by 'expand_code'. + ''' cmd = ['clang-format', '--style=file', '--verbose', '-i'] dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{lib.lower()}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys() for lib in ALL_LIBS] cmd.extend(dirs_to_format) @@ -230,79 +254,63 @@ def format_expand(): def format_code(source: bool, tests: bool): + ''' + Format all source files from the main library or test files. + ''' if source: - execute_command(['find', './src/', '-iname', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) + execute_command(['find', './src/', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) if tests: - execute_command(['find', './tests/', '-iname', '*.c', '-o', '-iname', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) + execute_command(['find', './tests/', '-name', '*.c', '-o', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) def build_tests(with_coverage: bool): + ''' + Build all object files and the main executable for tests + ''' cflags = CFLAGS.copy() if with_coverage: cflags += CVFLAGS - - print("WIP") - - -def run_tests(): - execute_command([TEST_EXE]) - - -def unused(): - # Makefile - # Contains many usefull things dealing with tests, code coverage and formatting - - print('Updating Makefile...') - - file = open(f'Makefile', 'w') - - file.write(f'''# This file was generated by a Python script - CC = {CC} - CFLAGS = -std=c11 -Wall -Wextra - CFLAGS += -Wno-missing-braces -DCMC_TEST_COLOR - CVFLAGS = --coverage -O0 -g3 - INCLUDE = {INCLUDE_DIR} -I src - - # Runs the script to update tests, run all tests and code coverage - all: script coverage - - tests: script build - \t{OUTPUT_DIR}/main.exe - - # Like build but with coverage - coverage: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])} {OBJ_DIR}/main.o - \t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) $(CVFLAGS) - \t{OUTPUT_DIR}/main.exe - \tgcov {OBJ_DIR}/main.o {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])} - - # Run without coverage - run: build - \t{OUTPUT_DIR}/main.exe - - script: - \tpython autogen.py - - clean: - \tfind {BUILD_DIR} -type f -delete - \trm *.gcov - - # No coverage build - build: {' '.join([f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS])} {OBJ_DIR}/main.o - \t$(CC) $^ -o {OUTPUT_DIR}/main.exe $(CFLAGS) - - {OBJ_DIR}/main.o: {OUTPUT_DIR}/main.c - \t$(CC) -c $^ -o $@ -I $(INCLUDE) $(CFLAGS) - ''') + else: + cflags += ['-O3'] for data in COLLECTIONS: - file.write(f''' - {OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o: {SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c {INCLUDE_DIR}/{data['LIB'].lower()}/{data['SNAME']}.h - \t$(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - ''') + cmd = [CC] + cmd += cflags + cmd += TINCLUDE # This one needs to go first + cmd += INCLUDE + cmd += ['-c', f"{SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c"] + cmd += ['-o', f"{OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o"] + execute_command(cmd) - file.close() - print('\nDone') + # Build OUTPUT_DIR/main.c + cmd = [CC] + cmd += cflags + cmd += TINCLUDE # This one needs to go first + cmd += INCLUDE + cmd += ['-c', f'{OUTPUT_DIR}/main.c'] + cmd += ['-o', f"{OBJ_DIR}/main.o"] + execute_command(cmd) + + # Link everything producing OUTPUT_DIR/main.exe + cmd = [CC] + cmd += cflags + cmd += ['-o', TEST_EXE] + cmd += [f'{OBJ_DIR}/main.o'] + cmd += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS] + execute_command(cmd) + + +def run_tests(coverage: bool): + ''' + Runs tests. If coverage, run gcov. + ''' + execute_command([full_path(TEST_EXE)]) + + if coverage: + objects = [f'{OBJ_DIR}/main.o'] + objects += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS] + execute_command(['gcov'] + objects) if __name__ == '__main__': @@ -320,6 +328,11 @@ if __name__ == '__main__': default=False, action='store_true', dest='clean') + tests.add_argument('-cf', '--clean-full', + help='Cleans all build objects, source and header files, and removes folders', + default=False, + action='store_true', + dest='cleanfull') tests.add_argument('-e', '--expand', help='Expands the header and source files', default=False, @@ -330,18 +343,23 @@ if __name__ == '__main__': default=False, action='store_true', dest='noformat') + tests.add_argument('-b', '--build', + help='Compile the object files and the main executable', + default=False, + action='store_true', + dest='build') tests.add_argument('-r', '--run', - help='Runs tests without code coverage', + help='Runs tests, assuming that it is already built', default=False, action='store_true', dest='run') tests.add_argument('-cv', '--coverage', - help='Compiles and runs tests with code coverage', + help='Adds the code coverage flags for compilation', default=False, action='store_true', dest='coverage') tests.add_argument('-rr', '--rerun', - help='Builds tests without code coverage and runs it', + help='Compile the object files again and then run the tests', default=False, action='store_true', dest='rerun') @@ -365,11 +383,12 @@ if __name__ == '__main__': print(CONFIG) exit(0) - if args.clean: - clean_build() + if args.clean or args.cleanfull: + clean_build(args.cleanfull) - assert_structure() - assert_executable(CC) + if not args.cleanfull: + assert_structure() + assert_executable(CC) if args.expand: expand_code() @@ -382,11 +401,12 @@ if __name__ == '__main__': assert_executable('xargs') format_code(args.fmt_source, args.fmt_tests) - if args.rerun: - build_tests(False) - run_tests() + if args.build: + build_tests(args.coverage) + if args.run: + run_tests(args.coverage) + elif args.rerun: + build_tests(args.coverage) + run_tests(args.coverage) elif args.run: - run_tests() - elif args.coverage: - build_tests(True) - run_tests() + run_tests(args.coverage) diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 54ca72c..0406261 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -461,8 +461,8 @@ return false; \ } \ \ - K max_key; \ - V max_val; \ + K max_key = (K) { 0 }; \ + V max_val = (V) { 0 }; \ size_t first = 0; \ \ for (; first < _map_->capacity; first++) \ @@ -505,8 +505,8 @@ return false; \ } \ \ - K min_key; \ - V min_val; \ + K min_key = (K) { 0 }; \ + V min_val = (V) { 0 }; \ size_t first = 0; \ \ for (; first < _map_->capacity; first++) \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index 51a700a..053f55f 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -684,8 +684,8 @@ return false; \ } \ \ - K max_key; \ - V max_val; \ + K max_key = (K) { 0 }; \ + V max_val = (V) { 0 }; \ \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ \ @@ -728,8 +728,8 @@ return false; \ } \ \ - K min_key; \ - V min_val; \ + K min_key = (K) { 0 }; \ + V min_val = (V) { 0 }; \ \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index f94ac96..be14e5f 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -477,7 +477,7 @@ return false; \ } \ \ - V max_val; \ + V max_val = (V) { 0 }; \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO transform this into a normal loop */ \ @@ -510,7 +510,7 @@ return false; \ } \ \ - V min_val; \ + V min_val = (V) { 0 }; \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO transform this into a normal loop */ \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 04b2c2e..47bdf4f 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -378,7 +378,7 @@ return false; \ } \ \ - V max_value; \ + V max_val = (V) { 0 }; \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO turn this into a normal loop */ \ @@ -388,13 +388,13 @@ size_t index = CMC_(PFX, _iter_index)(&iter); \ \ if (index == 0) \ - max_value = result; \ - else if (_set_->f_val->cmp(result, max_value) > 0) \ - max_value = result; \ + max_val = result; \ + else if (_set_->f_val->cmp(result, max_val) > 0) \ + max_val = result; \ } \ \ if (value) \ - *value = max_value; \ + *value = max_val; \ \ _set_->flag = CMC_FLAG_OK; \ \ @@ -411,7 +411,7 @@ return false; \ } \ \ - V min_value; \ + V min_val = (V) { 0 }; \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO turn this into a normal loop */ \ @@ -421,13 +421,13 @@ size_t index = CMC_(PFX, _iter_index)(&iter); \ \ if (index == 0) \ - min_value = result; \ - else if (_set_->f_val->cmp(result, min_value) < 0) \ - min_value = result; \ + min_val = result; \ + else if (_set_->f_val->cmp(result, min_val) < 0) \ + min_val = result; \ } \ \ if (value) \ - *value = min_value; \ + *value = min_val; \ \ _set_->flag = CMC_FLAG_OK; \ \ diff --git a/tests/include/cmc/queue.h b/tests/include/cmc/queue.h index 33b4904..1fcd7b1 100644 --- a/tests/include/cmc/queue.h +++ b/tests/include/cmc/queue.h @@ -25,14 +25,6 @@ struct queue_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct queue_iter -{ - struct queue *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; struct queue *q_new(size_t capacity, struct queue_fval *f_val); struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -51,6 +43,14 @@ int q_flag(struct queue *_queue_); _Bool q_resize(struct queue *_queue_, size_t capacity); struct queue *q_copy_of(struct queue *_queue_); _Bool q_equals(struct queue *_queue1_, struct queue *_queue2_); +struct queue_iter +{ + struct queue *target; + size_t cursor; + size_t index; + _Bool start; + _Bool end; +}; struct queue_iter q_iter_start(struct queue *target); struct queue_iter q_iter_end(struct queue *target); _Bool q_iter_at_start(struct queue_iter *iter); diff --git a/tests/src/cmc/hashmap.c b/tests/src/cmc/hashmap.c index 7fb16b5..20f99e5 100644 --- a/tests/src/cmc/hashmap.c +++ b/tests/src/cmc/hashmap.c @@ -201,8 +201,8 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - size_t max_key; - size_t max_val; + size_t max_key = (size_t){ 0 }; + size_t max_val = (size_t){ 0 }; size_t first = 0; for (; first < _map_->capacity; first++) { @@ -240,8 +240,8 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - size_t min_key; - size_t min_val; + size_t min_key = (size_t){ 0 }; + size_t min_val = (size_t){ 0 }; size_t first = 0; for (; first < _map_->capacity; first++) { diff --git a/tests/src/cmc/hashmultimap.c b/tests/src/cmc/hashmultimap.c index 45ef628..41d0817 100644 --- a/tests/src/cmc/hashmultimap.c +++ b/tests/src/cmc/hashmultimap.c @@ -353,8 +353,8 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - size_t max_key; - size_t max_val; + size_t max_key = (size_t){ 0 }; + size_t max_val = (size_t){ 0 }; struct hashmultimap_iter iter = hmm_iter_start(_map_); for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter)) { @@ -389,8 +389,8 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - size_t min_key; - size_t min_val; + size_t min_key = (size_t){ 0 }; + size_t min_val = (size_t){ 0 }; struct hashmultimap_iter iter = hmm_iter_start(_map_); for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter)) { diff --git a/tests/src/cmc/hashmultiset.c b/tests/src/cmc/hashmultiset.c index e348d67..6aa25a2 100644 --- a/tests/src/cmc/hashmultiset.c +++ b/tests/src/cmc/hashmultiset.c @@ -218,7 +218,7 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } - size_t max_val; + size_t max_val = (size_t){ 0 }; struct hashmultiset_iter iter = hms_iter_start(_set_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { @@ -244,7 +244,7 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } - size_t min_val; + size_t min_val = (size_t){ 0 }; struct hashmultiset_iter iter = hms_iter_start(_set_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { diff --git a/tests/src/cmc/hashset.c b/tests/src/cmc/hashset.c index de158d7..e0605f1 100644 --- a/tests/src/cmc/hashset.c +++ b/tests/src/cmc/hashset.c @@ -164,19 +164,19 @@ _Bool hs_max(struct hashset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } - size_t max_value; + size_t max_val = (size_t){ 0 }; struct hashset_iter iter = hs_iter_start(_set_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t result = hs_iter_value(&iter); size_t index = hs_iter_index(&iter); if (index == 0) - max_value = result; - else if (_set_->f_val->cmp(result, max_value) > 0) - max_value = result; + max_val = result; + else if (_set_->f_val->cmp(result, max_val) > 0) + max_val = result; } if (value) - *value = max_value; + *value = max_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read(); @@ -190,19 +190,19 @@ _Bool hs_min(struct hashset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } - size_t min_value; + size_t min_val = (size_t){ 0 }; struct hashset_iter iter = hs_iter_start(_set_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t result = hs_iter_value(&iter); size_t index = hs_iter_index(&iter); if (index == 0) - min_value = result; - else if (_set_->f_val->cmp(result, min_value) < 0) - min_value = result; + min_val = result; + else if (_set_->f_val->cmp(result, min_val) < 0) + min_val = result; } if (value) - *value = min_value; + *value = min_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read(); From e1bb3542ee6d8145c3ab9681ee4a39d50a4cb24a Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 22 Jun 2020 23:27:20 -0300 Subject: [PATCH 42/51] Updating autogen.py --- .travis.yml | 2 +- autogen.py | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 13ec3b0..5fc178b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,6 @@ script: - export CC=gcc-9 - gcc --version - python --version - - python autogen.py -e -b -cv -r + - python autogen.py -e -b -cv -r -nf after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/autogen.py b/autogen.py index b5b2644..1073528 100644 --- a/autogen.py +++ b/autogen.py @@ -43,6 +43,8 @@ SRC_DIR = f"{OUTPUT_DIR}/{DIR_MAP['SOURCE']}" OBJ_DIR = BUILD_DIR # The name of the main test executable TEST_EXE = f'{OUTPUT_DIR}/main.exe' +# Where .gcov files should go +GCOV_DIR = f'{BUILD_DIR}/gcov' # Compiler @@ -50,8 +52,12 @@ TEST_EXE = f'{OUTPUT_DIR}/main.exe' CC = 'gcc' # Compilation Flags CFLAGS = ['-Wall', '-Werror'] +# Link flags +LFLAGS = [] # Coverage Flags CVFLAGS = ['--coverage', '-O0'] +# gcov flags +GCOV_FLAGS = [] # Include to the main Library # const INCLUDE = ['-I', './src'] @@ -82,10 +88,13 @@ CONFIG = f'''Directory Settings INCLUDE_DIR = {INCLUDE_DIR} SRC_DIR = {SRC_DIR} OBJ_DIR = {OBJ_DIR} + GCOV_DIR = {GCOV_DIR} Compiler Settings CC = {CC} CFLAGS = {CFLAGS} + LFLAGS = {LFLAGS} CVFLAGS = {CVFLAGS} + GCOV_FLAGS = {GCOV_FLAGS} INCLUDE = {INCLUDE} TINCLUDE = {TINCLUDE} Macro Expansion @@ -165,6 +174,7 @@ def assert_structure(): assert_dir(BUILD_DIR) assert_dir(OBJ_DIR) + assert_dir(GCOV_DIR) for lib in ALL_LIBS: assert_dir(f'{OBJ_DIR}/{lib.lower()}') @@ -174,11 +184,13 @@ def clean_build(cleanfull: bool): ''' Removes all files generated by compilation and code coverage along with folders. ''' - execute_command(['rm', '-r', '*.gcov']) + execute_command(['rm', '-r', f'{GCOV_DIR}/*.gcov']) execute_command(['rm', TEST_EXE]) + execute_command(['rm', '-r', BUILD_DIR]) - for directory in [BUILD_DIR, SRC_DIR, INCLUDE_DIR]: - execute_command(['rm', '-r', directory]) + if cleanfull: + execute_command(['rm', '-r', SRC_DIR]) + execute_command(['rm', '-r', INCLUDE_DIR]) def expand_code(): @@ -268,6 +280,7 @@ def build_tests(with_coverage: bool): Build all object files and the main executable for tests ''' cflags = CFLAGS.copy() + lflags = CFLAGS.copy() if with_coverage: cflags += CVFLAGS @@ -295,6 +308,7 @@ def build_tests(with_coverage: bool): # Link everything producing OUTPUT_DIR/main.exe cmd = [CC] cmd += cflags + cmd += LFLAGS cmd += ['-o', TEST_EXE] cmd += [f'{OBJ_DIR}/main.o'] cmd += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS] @@ -308,9 +322,10 @@ def run_tests(coverage: bool): execute_command([full_path(TEST_EXE)]) if coverage: - objects = [f'{OBJ_DIR}/main.o'] - objects += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS] - execute_command(['gcov'] + objects) + objects = [f'{OBJ_DIR}/main.gcda'] + objects += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.gcda' for data in COLLECTIONS] + execute_command(['gcov'] + GCOV_FLAGS + objects) + execute_command(['mv', '*.gcov', GCOV_DIR]) if __name__ == '__main__': @@ -395,6 +410,10 @@ if __name__ == '__main__': if not args.noformat: assert_executable('clang-format') format_expand() + else: + # In case the next task is to build the code from source + # This warning is a very annoying one from gcc + CFLAGS += ['-Wno-misleading-indentation'] if args.fmt_source or args.fmt_tests: assert_executable('find') From c93f4bac6b7e5f859d125ba7c9560f11565a2cff Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 23 Jun 2020 22:09:09 -0300 Subject: [PATCH 43/51] Update autogen.py --- autogen.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/autogen.py b/autogen.py index 1073528..bb4bec0 100644 --- a/autogen.py +++ b/autogen.py @@ -28,7 +28,7 @@ from typing import List, Text # included: main.c, unt folder OUTPUT_DIR = './tests' # All libraries -ALL_LIBS = ['CMC', 'SAC', 'TSC'] +ALL_LIBS = ['CMC'] # Directory mapping DIR_MAP = {'HEADER': 'include', 'SOURCE': 'src'} # File extension mapping @@ -133,8 +133,9 @@ def full_path(path: Text) -> Text: def execute_command(commands: List[Text]): - print(' '.join(commands)) - cp = subprocess.run(commands, shell=True) + cmd = ' '.join(commands) + print(cmd) + subprocess.check_call(cmd, shell=True) # if cp.returncode != 0: # print('Error when executing the last command') @@ -184,9 +185,10 @@ def clean_build(cleanfull: bool): ''' Removes all files generated by compilation and code coverage along with folders. ''' - execute_command(['rm', '-r', f'{GCOV_DIR}/*.gcov']) - execute_command(['rm', TEST_EXE]) - execute_command(['rm', '-r', BUILD_DIR]) + # -f prevents 'rm' from failing + execute_command(['rm', '-r', '-f', f'{GCOV_DIR}/*.gcov']) + execute_command(['rm', '-f', TEST_EXE]) + execute_command(['rm', '-r', '-f', BUILD_DIR]) if cleanfull: execute_command(['rm', '-r', SRC_DIR]) @@ -280,7 +282,6 @@ def build_tests(with_coverage: bool): Build all object files and the main executable for tests ''' cflags = CFLAGS.copy() - lflags = CFLAGS.copy() if with_coverage: cflags += CVFLAGS From a23dfb0ab0ee565a27fe3cab6eebdaa9fcdb5141 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 23 Jun 2020 22:34:30 -0300 Subject: [PATCH 44/51] Update .travis.yml --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5fc178b..080b8a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,12 @@ addons: - cmake - python3.8 script: + - sudo rm gcc gcov python - sudo ln -s /usr/bin/gcc-9 /usr/local/bin/gcc + - sudo ln -s /usr/bin/gcov-9 /usr/local/bin/gcov - sudo ln -s /usr/bin/python3.8 /usr/local/bin/python - - export CC=gcc-9 - gcc --version + - gcov --version - python --version - python autogen.py -e -b -cv -r -nf after_success: From ce470f50b5862c9ecfbd2b6d681ea4fa802f5333 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 23 Jun 2020 23:17:54 -0300 Subject: [PATCH 45/51] Update .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 080b8a8..eb93d61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ addons: - cmake - python3.8 script: - - sudo rm gcc gcov python - sudo ln -s /usr/bin/gcc-9 /usr/local/bin/gcc - sudo ln -s /usr/bin/gcov-9 /usr/local/bin/gcov - sudo ln -s /usr/bin/python3.8 /usr/local/bin/python From fe056c1b06398fa844fac47d18b859ca22883692 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 24 Jun 2020 16:57:38 -0300 Subject: [PATCH 46/51] Some fixes to bitset --- src/cmc/bitset.h | 44 ++++++++++++++++---------------------- src/cor/bitset.h | 16 ++++++++++++++ tests/include/cmc/bitset.h | 9 +------- tests/src/cmc/bitset.c | 26 +++++++++++----------- tests/unt/cmc/bitset.h | 30 +++++++++++++------------- 5 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index 9dff4a7..796d016 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -85,6 +85,11 @@ \ /* Current array capacity */ \ size_t capacity; \ +\ + /* Currently used bits */\ + /* This should always be true: */\ + /* capacity - count < sizeof(cmc_bitset_word) * CHAR_BIT */\ + size_t count;\ \ /* Flags indicating errors or success */ \ int flag; \ @@ -152,19 +157,6 @@ /* Iterator State */ \ /* Iterator Movement */ \ /* Iterator Access */ \ -\ - /* Utility Methods */ \ - /* Translates a bit index to a word index */ \ - static inline size_t CMC_(PFX, _bit_to_index)(size_t idx) \ - { \ - /* Calculate how many shifts based on the size of cmc_bitset_word */ \ - static const size_t shift = \ - ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \ - ? 6 \ - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; \ -\ - return idx >> shift; \ - } /* ------------------------------------------------------------------------- * Source @@ -190,7 +182,7 @@ if (!alloc) \ alloc = &cmc_alloc_node_default; \ \ - size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; \ \ struct SNAME *_bitset_ = alloc->malloc(sizeof(struct SNAME)); \ \ @@ -231,7 +223,7 @@ if (!alloc) \ alloc = &cmc_alloc_node_default; \ \ - size_t capacity = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; \ \ _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ \ @@ -280,7 +272,7 @@ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ + size_t i = cmc_bidx_to_widx(bit_index); \ \ _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); \ \ @@ -302,8 +294,8 @@ if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ + size_t start_index = cmc_bidx_to_widx(from); \ + size_t end_index = cmc_bidx_to_widx(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -346,7 +338,7 @@ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ + size_t i = cmc_bidx_to_widx(bit_index); \ \ _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); \ \ @@ -368,8 +360,8 @@ if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ + size_t start_index = cmc_bidx_to_widx(from); \ + size_t end_index = cmc_bidx_to_widx(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -412,7 +404,7 @@ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - size_t i = CMC_(PFX, _bit_to_index)(bit_index); \ + size_t i = cmc_bidx_to_widx(bit_index); \ \ _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); \ \ @@ -434,8 +426,8 @@ if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ return false; \ \ - size_t start_index = CMC_(PFX, _bit_to_index)(from); \ - size_t end_index = CMC_(PFX, _bit_to_index)(to); \ + size_t start_index = cmc_bidx_to_widx(from); \ + size_t end_index = cmc_bidx_to_widx(to); \ \ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ @@ -527,7 +519,7 @@ /* How many bits in a word */ \ const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ \ - cmc_bitset_word w = _bitset_->buffer[CMC_(PFX, _bit_to_index)(bit_index)]; \ + cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; \ \ return w & ((cmc_bitset_word)1 << (bit_index % bits)); \ } \ @@ -549,7 +541,7 @@ \ /* -1 because n_bits is 1-based and we need to pass a 0-based index */ \ /* +1 to have a 1-based result */ \ - size_t words = CMC_(PFX, _bit_to_index)(n_bits - 1) + 1; \ + size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; \ \ /* Be sure we are not always shrinking when we just want to make */ \ /* sure that we have enough size for n_bits */ \ diff --git a/src/cor/bitset.h b/src/cor/bitset.h index 29901a5..9f793af 100644 --- a/src/cor/bitset.h +++ b/src/cor/bitset.h @@ -25,4 +25,20 @@ typedef CMC_BITSET_WORD_TYPE cmc_bitset_word; +/** + * cmc_bit_to_index + * + * Translates a bit index to a word index + */ +static inline size_t cmc_bidx_to_widx(size_t idx) +{ + /* Calculate how many shifts based on the size of cmc_bitset_word */ + static const size_t shift = + ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 + ? 6 + : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; + + return idx >> shift; +} + #endif /* CMC_COR_BITSET_H */ diff --git a/tests/include/cmc/bitset.h b/tests/include/cmc/bitset.h index 0918550..0c693e0 100644 --- a/tests/include/cmc/bitset.h +++ b/tests/include/cmc/bitset.h @@ -8,6 +8,7 @@ struct bitset { cmc_bitset_word *buffer; size_t capacity; + size_t count; int flag; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; @@ -39,13 +40,5 @@ _Bool bs_clear_all(struct bitset *_bitset_); _Bool bs_flip_all(struct bitset *_bitset_); _Bool bs_get(struct bitset *_bitset_, size_t bit_index); _Bool bs_resize(struct bitset *_bitset_, size_t n_bits); -static inline size_t bs_bit_to_index(size_t idx) -{ - static const size_t shift = - ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 - ? 6 - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; - return idx >> shift; -} #endif /* CMC_CMC_BITSET_TEST_H */ diff --git a/tests/src/cmc/bitset.c b/tests/src/cmc/bitset.c index 68baf71..39865ba 100644 --- a/tests/src/cmc/bitset.c +++ b/tests/src/cmc/bitset.c @@ -13,7 +13,7 @@ struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; - size_t capacity = bs_bit_to_index(n_bits - 1) + 1; + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset)); if (!_bitset_) return ((void *)0); @@ -42,7 +42,7 @@ struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, return _bitset_; if (!alloc) alloc = &cmc_alloc_node_default; - size_t capacity = bs_bit_to_index(n_bits - 1) + 1; + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); if (!_bitset_.buffer) return _bitset_; @@ -76,7 +76,7 @@ _Bool bs_set(struct bitset *_bitset_, size_t bit_index) if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = bs_bit_to_index(bit_index); + size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) @@ -93,8 +93,8 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; - size_t start_index = bs_bit_to_index(from); - size_t end_index = bs_bit_to_index(to); + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; @@ -123,7 +123,7 @@ _Bool bs_clear(struct bitset *_bitset_, size_t bit_index) if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = bs_bit_to_index(bit_index); + size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) @@ -140,8 +140,8 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; - size_t start_index = bs_bit_to_index(from); - size_t end_index = bs_bit_to_index(to); + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; @@ -170,7 +170,7 @@ _Bool bs_flip(struct bitset *_bitset_, size_t bit_index) if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = bs_bit_to_index(bit_index); + size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) @@ -187,8 +187,8 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; - size_t start_index = bs_bit_to_index(from); - size_t end_index = bs_bit_to_index(to); + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; @@ -259,7 +259,7 @@ _Bool bs_flip_all(struct bitset *_bitset_) _Bool bs_get(struct bitset *_bitset_, size_t bit_index) { const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - cmc_bitset_word w = _bitset_->buffer[bs_bit_to_index(bit_index)]; + cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; return w & ((cmc_bitset_word)1 << (bit_index % bits)); } _Bool bs_resize(struct bitset *_bitset_, size_t n_bits) @@ -273,7 +273,7 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) _bitset_->flag = CMC_FLAG_INVALID; return 0; } - size_t words = bs_bit_to_index(n_bits - 1) + 1; + size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; if (!do_resize && words <= _bitset_->capacity) return 1; cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); diff --git a/tests/unt/cmc/bitset.h b/tests/unt/cmc/bitset.h index 41f490e..daf9757 100644 --- a/tests/unt/cmc/bitset.h +++ b/tests/unt/cmc/bitset.h @@ -20,7 +20,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert_not_equals(ptr, NULL, bs); cmc_assert_not_equals(ptr, NULL, bs->buffer); - cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs->capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs->capacity); cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs->alloc->malloc); cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs->alloc->calloc); cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs->alloc->realloc); @@ -31,7 +31,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { bs = bs_new(129); - cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs->capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity); bs_free(bs); @@ -45,7 +45,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert_not_equals(ptr, NULL, bs); cmc_assert_not_equals(ptr, NULL, bs->buffer); - cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs->capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs->capacity); cmc_assert_equals(ptr, bs_alloc_node, bs->alloc); cmc_assert_equals(ptr, callbacks, bs->callbacks); @@ -53,7 +53,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { bs = bs_new_custom(129, NULL, NULL); - cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs->capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity); bs_free(bs); bs = bs_new_custom(0, bs_alloc_node, callbacks); @@ -65,7 +65,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { struct bitset bs = bs_init(64); cmc_assert_not_equals(ptr, NULL, bs.buffer); - cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs.capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs.capacity); cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs.alloc->malloc); cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs.alloc->calloc); cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs.alloc->realloc); @@ -76,7 +76,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { bs = bs_init(129); - cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs.capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity); bs_release(bs); @@ -89,7 +89,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { struct bitset bs = bs_init_custom(64, bs_alloc_node, callbacks); cmc_assert_not_equals(ptr, NULL, bs.buffer); - cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs.capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs.capacity); cmc_assert_equals(ptr, bs_alloc_node, bs.alloc); cmc_assert_equals(ptr, callbacks, bs.callbacks); @@ -97,7 +97,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { bs = bs_init_custom(129, NULL, NULL); - cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs.capacity); + cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity); bs_release(bs); @@ -149,11 +149,11 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert(bs_set(bs, word_bits * 8 - 1)); cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)), - bs->buffer[bs_bit_to_index(word_bits * 8 - 1)]); + bs->buffer[cmc_bidx_to_widx(word_bits * 8 - 1)]); cmc_assert(bs_set(bs, word_bits * 18 - 2)); cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)), - bs->buffer[bs_bit_to_index(word_bits * 18 - 2)]); + bs->buffer[cmc_bidx_to_widx(word_bits * 18 - 2)]); bs_free(bs); }); @@ -182,16 +182,16 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert(bs_set_range(bs, word_bits * 6 - 2, word_bits * 6 - 2)); cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)), - bs->buffer[bs_bit_to_index(word_bits * 6 - 2)]); + bs->buffer[cmc_bidx_to_widx(word_bits * 6 - 2)]); // Make sure we have at least word_bits * 40 slots bs_set(bs, word_bits * 40); cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0), bs->buffer[bs_bit_to_index(word_bits * 20)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0), bs->buffer[cmc_bidx_to_widx(word_bits * 20)]); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[bs_bit_to_index(word_bits * 20 - 1)]); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[bs_bit_to_index(word_bits * 21 + 1)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 20 - 1)]); + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 21 + 1)]); cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1)); cmc_assert_equals(size_t, 100, bs->capacity); @@ -238,7 +238,7 @@ CMC_CREATE_UNIT(CMCBitSet, true, { cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1)); cmc_assert(bs_clear_range(bs, word_bits * 20, word_bits * 21 - 1)); - cmc_assert_equals(uint32_t, 0, bs->buffer[bs_bit_to_index(word_bits * 20)]); + cmc_assert_equals(uint32_t, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 20)]); for (size_t i = 0; i < bs->capacity; i++) bs->buffer[i] = ~((cmc_bitset_word)0); From 4d4f1256ee3b3bac82f18c379aa9ab6131fb81ed Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 24 Jun 2020 19:31:42 -0300 Subject: [PATCH 47/51] Some fixes to treeset and flags --- src/cmc/treeset.h | 508 +--------------------------------- src/cor/flags.h | 18 +- src/ext/cmc/treeset.h | 529 +++++++++++++++++++++++++++++++++++- tests/include/cmc/treeset.h | 38 +-- tests/src/cmc/treeset.c | 418 ++++++++++++++-------------- 5 files changed, 764 insertions(+), 747 deletions(-) diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h index 9b9ed6c..be3ffd4 100644 --- a/src/cmc/treeset.h +++ b/src/cmc/treeset.h @@ -130,31 +130,6 @@ /* Priority function */ \ CMC_DEF_FTAB_PRI(V); \ }; \ -\ - /* Treeset Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target treeset */ \ - struct SNAME *target; \ -\ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ -\ - /* The first node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * first; \ -\ - /* The last node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * last; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ \ /* Collection Functions */ \ /* Collection Allocation and Deallocation */ \ @@ -179,37 +154,7 @@ int CMC_(PFX, _flag)(struct SNAME * _set_); \ /* Collection Utility */ \ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); \ -\ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_); \ -\ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); /* ------------------------------------------------------------------------- * Source @@ -663,457 +608,6 @@ \ return true; \ } \ -\ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - /** TODO Should this compare count or capacity? */ \ - struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set_B_, value) != NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ -\ - if (CMC_(PFX, _impl_get_node)(_set1_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - /* Is _set1_ a subset of _set2_ ? */ \ - /* A set X is a subset of a set Y when: X <= Y */ \ - /* If X is a subset of Y, then Y is a superset of X */ \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* If the cardinality of _set1_ is greater than that of _set2_ */ \ - /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ - if (_set1_->count > _set2_->count) \ - return false; \ -\ - /* The empty set is a subset of all sets */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - /* Is _set1_ a superset of _set2_ ? */ \ - /* A set X is a superset of a set Y when: X >= Y */ \ - /* If X is a superset of Y, then Y is a subset of X */ \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ -\ - /* Is _set1_ a proper subset of _set2_ ? */ \ - /* A set X is a proper subset of a set Y when: X < Y */ \ - /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* If the cardinality of _set1_ is greater than or equal to that */ \ - /* of _set2_, then it is safe to say that _set1_ can't be a proper */ \ - /* subset of _set2_ */ \ - if (_set1_->count >= _set2_->count) \ - return false; \ -\ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - /* The empty set is a proper subset of all non-empty sets */ \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - /* The empty set is not a proper subset of itself (this is true */ \ - /* for any set) */ \ - else \ - return false; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - /* Is _set1_ a proper superset of _set2_ ? */ \ - /* A set X is a proper superset of a set Y when: X > Y */ \ - /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ -\ - /* Is _set1_ a disjointset of _set2_ ? */ \ - /* A set X is a disjointset of a set Y if their intersection is empty, */ \ - /* that is, if there are no elements in common between the two */ \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* The intersection of an empty set with any other set will result */ \ - /* in an empty set */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) != NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->left != NULL) \ - iter.cursor = iter.cursor->left; \ -\ - iter.first = iter.cursor; \ -\ - iter.last = target->root; \ - while (iter.last->right != NULL) \ - iter.last = iter.last->right; \ - } \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->right != NULL) \ - iter.cursor = iter.cursor->right; \ -\ - iter.last = iter.cursor; \ -\ - iter.first = target->root; \ - while (iter.first->left != NULL) \ - iter.first = iter.first->left; \ -\ - iter.index = target->count - 1; \ - } \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->first; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->cursor = iter->last; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->right != NULL) \ - { \ - iter->cursor = iter->cursor->right; \ -\ - while (iter->cursor->left != NULL) \ - iter->cursor = iter->cursor->left; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->left == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->left != NULL) \ - { \ - iter->cursor = iter->cursor->left; \ -\ - while (iter->cursor->right != NULL) \ - iter->cursor = iter->cursor->right; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->right == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->cursor->value; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ \ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value) \ { \ diff --git a/src/cor/flags.h b/src/cor/flags.h index 0a39e02..a9b0407 100644 --- a/src/cor/flags.h +++ b/src/cor/flags.h @@ -22,15 +22,15 @@ enum cmc_flags { CMC_FLAG_OK = 0, // No errors - CMC_FLAG_ALLOC = 2, // Allocation failed - CMC_FLAG_EMPTY = 3, // The collection is empty when it should not - CMC_FLAG_NOT_FOUND = 4, // Key or value not found - CMC_FLAG_INVALID = 5, // Invalid argument or operation - CMC_FLAG_RANGE = 6, // Index out of range - CMC_FLAG_DUPLICATE = 7, // Duplicate key or value - CMC_FLAG_ERROR = 8, // Generic error, usually caused by algorithm error - CMC_FLAG_THREAD = 9, // Generic error regarding threads - CMC_FLAG_MUTEX = 10 // Generic error regarding mutexes + CMC_FLAG_ALLOC = 1, // Allocation failed + CMC_FLAG_EMPTY = 2, // The collection is empty when it should not + CMC_FLAG_NOT_FOUND = 3, // Key or value not found + CMC_FLAG_INVALID = 4, // Invalid argument or operation + CMC_FLAG_RANGE = 5, // Index out of range + CMC_FLAG_DUPLICATE = 6, // Duplicate key or value + CMC_FLAG_ERROR = 7, // Generic error, usually caused by algorithm error + CMC_FLAG_THREAD = 8, // Generic error regarding threads + CMC_FLAG_MUTEX = 9 // Generic error regarding mutexes }; // clang-format on diff --git a/src/ext/cmc/treeset.h b/src/ext/cmc/treeset.h index 1e4f32d..674fef4 100644 --- a/src/ext/cmc/treeset.h +++ b/src/ext/cmc/treeset.h @@ -16,7 +16,7 @@ /** * All the EXT parts of CMC TreeSet. */ -#define CMC_EXT_CMC_TREESET_PARTS ITER, STR +#define CMC_EXT_CMC_TREESET_PARTS ITER, SETF, STR /** * ITER @@ -31,9 +31,532 @@ #define CMC_EXT_CMC_TREESET_ITER_SOURCE(PARAMS) \ CMC_EXT_CMC_TREESET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_TREESET_ITER_HEADER_(PFX, SNAME, V) +#define CMC_EXT_CMC_TREESET_ITER_HEADER_(PFX, SNAME, V) \ +\ + /* Treeset Iterator */ \ + struct CMC_DEF_ITER(SNAME) \ + { \ + /* Target treeset */ \ + struct SNAME *target; \ +\ + /* Cursor's current node */ \ + struct CMC_DEF_NODE(SNAME) * cursor; \ +\ + /* The first node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * first; \ +\ + /* The last node in the iteration */ \ + struct CMC_DEF_NODE(SNAME) * last; \ +\ + /* Keeps track of relative index to the iteration of elements */ \ + size_t index; \ +\ + /* If the iterator has reached the start of the iteration */ \ + bool start; \ +\ + /* If the iterator has reached the end of the iteration */ \ + bool end; \ + }; \ +\ + /* Iterator Initialization */ \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ + /* Iterator State */ \ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + /* Iterator Movement */ \ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ + /* Iterator Access */ \ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#define CMC_EXT_CMC_TREESET_ITER_SOURCE_(PFX, SNAME, V) \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = true; \ + iter.end = CMC_(PFX, _empty)(target); \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->left != NULL) \ + iter.cursor = iter.cursor->left; \ +\ + iter.first = iter.cursor; \ +\ + iter.last = target->root; \ + while (iter.last->right != NULL) \ + iter.last = iter.last->right; \ + } \ +\ + return iter; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ + { \ + struct CMC_DEF_ITER(SNAME) iter; \ +\ + iter.target = target; \ + iter.cursor = target->root; \ + iter.first = NULL; \ + iter.last = NULL; \ + iter.index = 0; \ + iter.start = CMC_(PFX, _empty)(target); \ + iter.end = true; \ +\ + if (!CMC_(PFX, _empty)(target)) \ + { \ + while (iter.cursor->right != NULL) \ + iter.cursor = iter.cursor->right; \ +\ + iter.last = iter.cursor; \ +\ + iter.first = target->root; \ + while (iter.first->left != NULL) \ + iter.first = iter.first->left; \ +\ + iter.index = target->count - 1; \ + } \ +\ + return iter; \ + } \ +\ + bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->start; \ + } \ +\ + bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return CMC_(PFX, _empty)(iter->target) || iter->end; \ + } \ +\ + bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = 0; \ + iter->start = true; \ + iter->end = CMC_(PFX, _empty)(iter->target); \ + iter->cursor = iter->first; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (!CMC_(PFX, _empty)(iter->target)) \ + { \ + iter->index = iter->target->count - 1; \ + iter->start = CMC_(PFX, _empty)(iter->target); \ + iter->end = true; \ + iter->cursor = iter->last; \ +\ + return true; \ + } \ +\ + return false; \ + } \ +\ + bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + iter->start = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->right != NULL) \ + { \ + iter->cursor = iter->cursor->right; \ +\ + while (iter->cursor->left != NULL) \ + iter->cursor = iter->cursor->left; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->left == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index++; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + iter->end = CMC_(PFX, _empty)(iter->target); \ +\ + if (iter->cursor->left != NULL) \ + { \ + iter->cursor = iter->cursor->left; \ +\ + while (iter->cursor->right != NULL) \ + iter->cursor = iter->cursor->right; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + while (true) \ + { \ + if (iter->cursor->parent->right == iter->cursor) \ + { \ + iter->cursor = iter->cursor->parent; \ +\ + iter->index--; \ +\ + return true; \ + } \ +\ + iter->cursor = iter->cursor->parent; \ + } \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->end) \ + return false; \ +\ + if (iter->cursor == iter->last) \ + { \ + iter->end = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index + steps >= iter->target->count) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_next)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator moved */ \ + bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ + { \ + if (iter->start) \ + return false; \ +\ + if (iter->cursor == iter->first) \ + { \ + iter->start = true; \ + return false; \ + } \ +\ + if (steps == 0 || iter->index < steps) \ + return false; \ +\ + for (size_t i = 0; i < steps; i++) \ + CMC_(PFX, _iter_prev)(iter); \ +\ + return true; \ + } \ +\ + /* Returns true only if the iterator was able to be positioned at the */ \ + /* given index */ \ + bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ + { \ + if (index >= iter->target->count) \ + return false; \ +\ + if (iter->index > index) \ + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ + else if (iter->index < index) \ + return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ +\ + return true; \ + } \ +\ + V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + if (CMC_(PFX, _empty)(iter->target)) \ + return (V){ 0 }; \ +\ + return iter->cursor->value; \ + } \ +\ + size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ + { \ + return iter->index; \ + } + +/** + * SETF + */ +#define CMC_EXT_CMC_TREESET_SETF(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_SOURCE(PARAMS) + +#define CMC_EXT_CMC_TREESET_SETF_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_SETF_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_SETF_HEADER_(PFX, SNAME, V) \ +\ + /* Set Operations */ \ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_); + +#define CMC_EXT_CMC_TREESET_SETF_SOURCE_(PFX, SNAME, V) \ +\ + struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + /** TODO Should this compare count or capacity? */ \ + struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ + struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set_B_, value) != NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ +\ + if (!_set_r_) \ + return NULL; \ +\ + struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ + struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter1); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter2); \ +\ + if (CMC_(PFX, _impl_get_node)(_set1_, value) == NULL) \ + CMC_(PFX, _insert)(_set_r_, value); \ + } \ +\ + CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ +\ + return _set_r_; \ + } \ +\ + /* Is _set1_ a subset of _set2_ ? */ \ + /* A set X is a subset of a set Y when: X <= Y */ \ + /* If X is a subset of Y, then Y is a superset of X */ \ + bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* If the cardinality of _set1_ is greater than that of _set2_ */ \ + /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ + if (_set1_->count > _set2_->count) \ + return false; \ +\ + /* The empty set is a subset of all sets */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + /* Is _set1_ a superset of _set2_ ? */ \ + /* A set X is a superset of a set Y when: X >= Y */ \ + /* If X is a superset of Y, then Y is a subset of X */ \ + bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_subset)(_set2_, _set1_); \ + } \ +\ + /* Is _set1_ a proper subset of _set2_ ? */ \ + /* A set X is a proper subset of a set Y when: X < Y */ \ + /* If X is a proper subset of Y, then Y is a proper superset of X */ \ + bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* If the cardinality of _set1_ is greater than or equal to that */ \ + /* of _set2_, then it is safe to say that _set1_ can't be a proper */ \ + /* subset of _set2_ */ \ + if (_set1_->count >= _set2_->count) \ + return false; \ +\ + if (CMC_(PFX, _empty)(_set1_)) \ + { \ + /* The empty set is a proper subset of all non-empty sets */ \ + if (!CMC_(PFX, _empty)(_set2_)) \ + return true; \ + /* The empty set is not a proper subset of itself (this is true */ \ + /* for any set) */ \ + else \ + return false; \ + } \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ + return false; \ + } \ +\ + return true; \ + } \ +\ + /* Is _set1_ a proper superset of _set2_ ? */ \ + /* A set X is a proper superset of a set Y when: X > Y */ \ + /* If X is a proper superset of Y, then Y is a proper subset of X */ \ + bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ + } \ +\ + /* Is _set1_ a disjointset of _set2_ ? */ \ + /* A set X is a disjointset of a set Y if their intersection is empty, */ \ + /* that is, if there are no elements in common between the two */ \ + bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \ + { \ + /* The intersection of an empty set with any other set will result */ \ + /* in an empty set */ \ + if (CMC_(PFX, _empty)(_set1_)) \ + return true; \ +\ + struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ +\ + for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + { \ + V value = CMC_(PFX, _iter_value)(&iter); \ +\ + if (CMC_(PFX, _impl_get_node)(_set2_, value) != NULL) \ + return false; \ + } \ +\ + return true; \ + } -#define CMC_EXT_CMC_TREESET_ITER_SOURCE_(PFX, SNAME, V) /** * STR diff --git a/tests/include/cmc/treeset.h b/tests/include/cmc/treeset.h index 432f272..9bca697 100644 --- a/tests/include/cmc/treeset.h +++ b/tests/include/cmc/treeset.h @@ -30,16 +30,6 @@ struct treeset_fval size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; -struct treeset_iter -{ - struct treeset *target; - struct treeset_node *cursor; - struct treeset_node *first; - struct treeset_node *last; - size_t index; - _Bool start; - _Bool end; -}; struct treeset *ts_new(struct treeset_fval *f_val); struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); @@ -56,15 +46,16 @@ size_t ts_count(struct treeset *_set_); int ts_flag(struct treeset *_set_); struct treeset *ts_copy_of(struct treeset *_set_); _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); +struct treeset_iter +{ + struct treeset *target; + struct treeset_node *cursor; + struct treeset_node *first; + struct treeset_node *last; + size_t index; + _Bool start; + _Bool end; +}; struct treeset_iter ts_iter_start(struct treeset *target); struct treeset_iter ts_iter_end(struct treeset *target); _Bool ts_iter_at_start(struct treeset_iter *iter); @@ -78,6 +69,15 @@ _Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); _Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); size_t ts_iter_value(struct treeset_iter *iter); size_t ts_iter_index(struct treeset_iter *iter); +struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); _Bool ts_to_string(struct treeset *_set_, FILE *fptr); _Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); diff --git a/tests/src/cmc/treeset.c b/tests/src/cmc/treeset.c index 795a020..5216b54 100644 --- a/tests/src/cmc/treeset.c +++ b/tests/src/cmc/treeset.c @@ -360,133 +360,120 @@ _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) } return 1; } -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) +static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) + struct treeset_node *node = _set_->alloc->malloc(sizeof(struct treeset_node)); + if (!node) return ((void *)0); - struct treeset_iter iter1 = ts_iter_start(_set1_); - struct treeset_iter iter2 = ts_iter_start(_set2_); - for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) - { - ts_insert(_set_r_, ts_iter_value(&iter1)); - } - for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) - { - ts_insert(_set_r_, ts_iter_value(&iter2)); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; + node->value = value; + node->right = ((void *)0); + node->left = ((void *)0); + node->parent = ((void *)0); + node->height = 0; + return node; } -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) +static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value) { - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct treeset_iter iter = ts_iter_start(_set_A_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + struct treeset_node *scan = _set_->root; + while (scan != ((void *)0)) { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set_B_, value) != ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter1 = ts_iter_start(_set1_); - struct treeset_iter iter2 = ts_iter_start(_set2_); - for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) - { - size_t value = ts_iter_value(&iter1); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) - { - size_t value = ts_iter_value(&iter2); - if (ts_impl_get_node(_set1_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (_set1_->count > _set2_->count) - return 0; - if (ts_empty(_set1_)) - return 1; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_) -{ - return ts_is_subset(_set2_, _set1_); -} -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (_set1_->count >= _set2_->count) - return 0; - if (ts_empty(_set1_)) - { - if (!ts_empty(_set2_)) - return 1; + if (_set_->f_val->cmp(scan->value, value) > 0) + scan = scan->left; + else if (_set_->f_val->cmp(scan->value, value) < 0) + scan = scan->right; else - return 0; + return scan; } - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - return 0; - } - return 1; + return ((void *)0); } -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_) +static unsigned char ts_impl_h(struct treeset_node *node) { - return ts_is_proper_subset(_set2_, _set1_); + if (node == ((void *)0)) + return 0; + return node->height; } -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_) +static unsigned char ts_impl_hupdate(struct treeset_node *node) { - if (ts_empty(_set1_)) - return 1; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + if (node == ((void *)0)) + return 0; + unsigned char h_l = ts_impl_h(node->left); + unsigned char h_r = ts_impl_h(node->right); + return 1 + (h_l > h_r ? h_l : h_r); +} +static void ts_impl_rotate_right(struct treeset_node **Z) +{ + struct treeset_node *root = *Z; + struct treeset_node *new_root = root->left; + if (root->parent != ((void *)0)) { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) != ((void *)0)) - return 0; + if (root->parent->left == root) + root->parent->left = new_root; + else + root->parent->right = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->left = new_root->right; + if (root->left) + root->left->parent = root; + new_root->right = root; + root->height = ts_impl_hupdate(root); + new_root->height = ts_impl_hupdate(new_root); + *Z = new_root; +} +static void ts_impl_rotate_left(struct treeset_node **Z) +{ + struct treeset_node *root = *Z; + struct treeset_node *new_root = root->right; + if (root->parent != ((void *)0)) + { + if (root->parent->right == root) + root->parent->right = new_root; + else + root->parent->left = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->right = new_root->left; + if (root->right) + root->right->parent = root; + new_root->left = root; + root->height = ts_impl_hupdate(root); + new_root->height = ts_impl_hupdate(new_root); + *Z = new_root; +} +static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) +{ + struct treeset_node *scan = node, *child = ((void *)0); + int balance; + _Bool is_root = 0; + while (scan != ((void *)0)) + { + if (scan->parent == ((void *)0)) + is_root = 1; + scan->height = ts_impl_hupdate(scan); + balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); + if (balance >= 2) + { + child = scan->right; + if (ts_impl_h(child->right) < ts_impl_h(child->left)) + ts_impl_rotate_right(&(scan->right)); + ts_impl_rotate_left(&scan); + } + else if (balance <= -2) + { + child = scan->left; + if (ts_impl_h(child->left) < ts_impl_h(child->right)) + ts_impl_rotate_left(&(scan->left)); + ts_impl_rotate_right(&scan); + } + if (is_root) + { + _set_->root = scan; + is_root = 0; + } + scan = scan->parent; } - return 1; } struct treeset_iter ts_iter_start(struct treeset *target) { @@ -671,120 +658,133 @@ size_t ts_iter_index(struct treeset_iter *iter) { return iter->index; } -static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value) +struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset_node *node = _set_->alloc->malloc(sizeof(struct treeset_node)); - if (!node) + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) return ((void *)0); - node->value = value; - node->right = ((void *)0); - node->left = ((void *)0); - node->parent = ((void *)0); - node->height = 0; - return node; -} -static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value) -{ - struct treeset_node *scan = _set_->root; - while (scan != ((void *)0)) + struct treeset_iter iter1 = ts_iter_start(_set1_); + struct treeset_iter iter2 = ts_iter_start(_set2_); + for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) { - if (_set_->f_val->cmp(scan->value, value) > 0) - scan = scan->left; - else if (_set_->f_val->cmp(scan->value, value) < 0) - scan = scan->right; - else - return scan; + ts_insert(_set_r_, ts_iter_value(&iter1)); } - return ((void *)0); + for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) + { + ts_insert(_set_r_, ts_iter_value(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; } -static unsigned char ts_impl_h(struct treeset_node *node) +struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) { - if (node == ((void *)0)) + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct treeset_iter iter = ts_iter_start(_set_A_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set_B_, value) != ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) +{ + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) +{ + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset_iter iter1 = ts_iter_start(_set1_); + struct treeset_iter iter2 = ts_iter_start(_set2_); + for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) + { + size_t value = ts_iter_value(&iter1); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) + { + size_t value = ts_iter_value(&iter2); + if (ts_impl_get_node(_set1_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (_set1_->count > _set2_->count) return 0; - return node->height; + if (ts_empty(_set1_)) + return 1; + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + return 0; + } + return 1; } -static unsigned char ts_impl_hupdate(struct treeset_node *node) +_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_) { - if (node == ((void *)0)) + return ts_is_subset(_set2_, _set1_); +} +_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (_set1_->count >= _set2_->count) return 0; - unsigned char h_l = ts_impl_h(node->left); - unsigned char h_r = ts_impl_h(node->right); - return 1 + (h_l > h_r ? h_l : h_r); -} -static void ts_impl_rotate_right(struct treeset_node **Z) -{ - struct treeset_node *root = *Z; - struct treeset_node *new_root = root->left; - if (root->parent != ((void *)0)) + if (ts_empty(_set1_)) { - if (root->parent->left == root) - root->parent->left = new_root; + if (!ts_empty(_set2_)) + return 1; else - root->parent->right = new_root; + return 0; } - new_root->parent = root->parent; - root->parent = new_root; - root->left = new_root->right; - if (root->left) - root->left->parent = root; - new_root->right = root; - root->height = ts_impl_hupdate(root); - new_root->height = ts_impl_hupdate(new_root); - *Z = new_root; -} -static void ts_impl_rotate_left(struct treeset_node **Z) -{ - struct treeset_node *root = *Z; - struct treeset_node *new_root = root->right; - if (root->parent != ((void *)0)) + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { - if (root->parent->right == root) - root->parent->right = new_root; - else - root->parent->left = new_root; + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + return 0; } - new_root->parent = root->parent; - root->parent = new_root; - root->right = new_root->left; - if (root->right) - root->right->parent = root; - new_root->left = root; - root->height = ts_impl_hupdate(root); - new_root->height = ts_impl_hupdate(new_root); - *Z = new_root; + return 1; } -static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) +_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_) { - struct treeset_node *scan = node, *child = ((void *)0); - int balance; - _Bool is_root = 0; - while (scan != ((void *)0)) + return ts_is_proper_subset(_set2_, _set1_); +} +_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (ts_empty(_set1_)) + return 1; + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { - if (scan->parent == ((void *)0)) - is_root = 1; - scan->height = ts_impl_hupdate(scan); - balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); - if (balance >= 2) - { - child = scan->right; - if (ts_impl_h(child->right) < ts_impl_h(child->left)) - ts_impl_rotate_right(&(scan->right)); - ts_impl_rotate_left(&scan); - } - else if (balance <= -2) - { - child = scan->left; - if (ts_impl_h(child->left) < ts_impl_h(child->right)) - ts_impl_rotate_left(&(scan->left)); - ts_impl_rotate_right(&scan); - } - if (is_root) - { - _set_->root = scan; - is_root = 0; - } - scan = scan->parent; + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) != ((void *)0)) + return 0; } + return 1; } _Bool ts_to_string(struct treeset *_set_, FILE *fptr) { From fa2e3d1fcd2c17a3ddd507336e432c8f767e7fb2 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 24 Jun 2020 21:55:20 -0300 Subject: [PATCH 48/51] Adding dfs example and fixing other examples --- examples/dfs.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++ examples/hanoi.c | 28 +++++++-------- examples/printer.c | 41 +++++++++++----------- examples/sieve.c | 2 +- 4 files changed, 122 insertions(+), 36 deletions(-) create mode 100644 examples/dfs.c diff --git a/examples/dfs.c b/examples/dfs.c new file mode 100644 index 0000000..9bb181a --- /dev/null +++ b/examples/dfs.c @@ -0,0 +1,87 @@ +/** + * Example of In-Order Depth-First Search using: + * - A Stack + * - Recursion + * - Without both + */ + +#define CMC_CAMEL_CASE + +#include "macro_collections.h" + +C_MACRO_COLLECTIONS_GEN(CMC, TREESET, (tree, BinaryTree, , , int32_t), (ITER, STR)) + +#define MYSTACK (stk, Stack, , , struct BinaryTreeNode *) + +C_MACRO_COLLECTIONS(CMC, STACK, CORE, STRUCT, MYSTACK) +C_MACRO_COLLECTIONS(CMC, STACK, CORE, HEADER, MYSTACK) +C_MACRO_COLLECTIONS(CMC, STACK, CORE, SOURCE, MYSTACK) + +void DFS(struct BinaryTreeNode *root) +{ + if (!root) + return; + + DFS(root->left); + + fprintf(stdout, "%d ", root->value); + + DFS(root->right); +} + +int main(void) +{ + struct BinaryTree *tree = tree_new(&(struct BinaryTreeFVal){ .cmp = cmc_i32_cmp, .str = cmc_i32_str, NULL }); + + for (int i = 1; i <= 10; i++) + tree_insert(tree, i); + + int32_t result = 1; + + cmc_assert(tree_min(tree, &result)); + cmc_assert_equals(int32_t, 1, result); + + cmc_assert(tree_max(tree, &result)); + cmc_assert_equals(int32_t, 10, result); + + printf("Without Recursion or Stack:\n"); + tree_print(tree, stdout, "[ ", " ", " ]\n"); + + printf("Recursion:\n"); + fprintf(stdout, "[ "); + DFS(tree->root); + fprintf(stdout, "]\n"); + + printf("Stack:\n"); + fprintf(stdout, "[ "); + struct Stack *stack = stk_new(100, &(struct StackFVal){ NULL }); + + struct BinaryTreeNode *node = tree->root; + + while (node || !stk_empty(stack)) + { + if (node) + { + if (!stk_push(stack, node)) + cmc_log_error("Could not push to stack %d\n", cmc_flags_to_str[stk_flag(stack)]); + + node = node->left; + } + else + { + node = stk_top(stack); + + if (!stk_pop(stack)) + cmc_log_error("Could not pop from the stack %s\n", cmc_flags_to_str[stk_flag(stack)]); + + fprintf(stdout, "%d ", node->value); + + node = node->right; + } + } + + stk_free(stack); + fprintf(stdout, "]\n"); + + tree_free(tree); +} diff --git a/examples/hanoi.c b/examples/hanoi.c index bc5504b..e4053b0 100644 --- a/examples/hanoi.c +++ b/examples/hanoi.c @@ -1,14 +1,17 @@ -#include -#include +#include "macro_collections.h" -CMC_GENERATE_STACK(stk, stack, int) +#define MYSTACK (stk, stack, , , int) + +C_MACRO_COLLECTIONS(CMC, STACK, CORE, STRUCT, MYSTACK) +C_MACRO_COLLECTIONS(CMC, STACK, CORE, HEADER, MYSTACK) +C_MACRO_COLLECTIONS(CMC, STACK, CORE, SOURCE, MYSTACK) struct { struct stack *from; struct stack *aux; struct stack *to; -} print_aux = {NULL}; +} print_aux = { NULL }; void print_stacks() { @@ -18,10 +21,7 @@ void print_stacks() int ib = print_aux.aux->buffer[i]; int ic = print_aux.to->buffer[i]; - printf("| %c | %c | %c |\n", - ia == 0 ? 32 : ia + 48, - ib == 0 ? 32 : ib + 48, - ic == 0 ? 32 : ic + 48); + printf("| %c | %c | %c |\n", ia == 0 ? 32 : ia + 48, ib == 0 ? 32 : ib + 48, ic == 0 ? 32 : ic + 48); } printf("+---+---+---+\n\n"); @@ -50,9 +50,9 @@ void hanoi(int n, struct stack *from, struct stack *aux, struct stack *to) int main(int argc, char const *argv[]) { - struct stack *from = stk_new(10); - struct stack *to = stk_new(10); - struct stack *aux = stk_new(10); + struct stack *from = stk_new(10, &(struct stack_fval){ NULL }); + struct stack *to = stk_new(10, &(struct stack_fval){ NULL }); + struct stack *aux = stk_new(10, &(struct stack_fval){ NULL }); for (int i = 4; i >= 1; i--) stk_push(from, i); @@ -65,9 +65,9 @@ int main(int argc, char const *argv[]) hanoi(stk_count(from), from, aux, to); - stk_free(from, NULL); - stk_free(to, NULL); - stk_free(aux, NULL); + stk_free(from); + stk_free(to); + stk_free(aux); return 0; } diff --git a/examples/printer.c b/examples/printer.c index 2b016cd..16667b7 100644 --- a/examples/printer.c +++ b/examples/printer.c @@ -1,5 +1,6 @@ -#include -#include +// Prints a file in the terminal separated by pages + +#include "macro_collections.h" #define TAB_SIZE 4 #define ROW_INI_CAP DOC_LETTERS_IN_ROW @@ -7,13 +8,11 @@ #define DOC_ROWS_IN_PAGE 50 #define DOC_MARGIN 4 -CMC_GENERATE_LIST(row, row, char) -CMC_GENERATE_LIST(doc, document, struct row *) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (row, row, , , char)) +C_MACRO_COLLECTIONS_ALL(CMC, LIST, (doc, document, , , struct row *)) -void row_deallocator(struct row *r) -{ - row_free(r, NULL); -} +struct row_fval *row_funcs = &(struct row_fval){ NULL }; +struct document_fval *doc_funcs = &(struct document_fval){ .free = row_free }; struct document *document_load(const char *file_name); void document_empty_line(FILE *fptr); @@ -31,9 +30,9 @@ struct document *document_load(const char *file_name) return NULL; } - struct row *initial_row = row_new(ROW_INI_CAP); + struct row *initial_row = row_new(ROW_INI_CAP, row_funcs); - struct document *doc = doc_new(100); + struct document *doc = doc_new(100, doc_funcs); doc_push_back(doc, initial_row); int ch; @@ -46,7 +45,7 @@ struct document *document_load(const char *file_name) if (c == '\n') { - struct row *new_row = row_new(ROW_INI_CAP); + struct row *new_row = row_new(ROW_INI_CAP, row_funcs); doc_push_back(doc, new_row); } else if (c == '\t') @@ -61,7 +60,7 @@ struct document *document_load(const char *file_name) if (left > 0) { - struct row *new_row = row_new(ROW_INI_CAP); + struct row *new_row = row_new(ROW_INI_CAP, row_funcs); doc_push_back(doc, new_row); while (left > 0) @@ -73,7 +72,7 @@ struct document *document_load(const char *file_name) } else if (DOC_LETTERS_IN_ROW == row_count(current_row)) { - struct row *new_row = row_new(ROW_INI_CAP); + struct row *new_row = row_new(ROW_INI_CAP, row_funcs); row_push_back(new_row, c); doc_push_back(doc, new_row); } @@ -86,12 +85,12 @@ struct document *document_load(const char *file_name) void document_empty_line(FILE *fptr) { - fputs("|", fptr); + fputs("\t|", fptr); for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2; i++) { fputc(' ', fptr); } - fputs("|\n", fptr); + fputs("\t|\n", fptr); } void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */) @@ -102,7 +101,7 @@ void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */) #ifdef DOC_PAGE_NUMBER static intmax_t page = 1; - fputs("|", fptr); + fputs("\t|", fptr); for (size_t i = 0; i < (DOC_LETTERS_IN_ROW + DOC_MARGIN) - 8; i++) { fputc(' ', fptr); @@ -116,8 +115,8 @@ void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */) #endif } - fputs("+", fptr); - for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2; i++) + fputs("\t+", fptr); + for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2 + 3; i++) { fputc('-', fptr); } @@ -130,7 +129,7 @@ void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */) void document_page_margin(FILE *fptr, int margin /* 0 - first margin, 1 - second margin */) { if (margin == 0) - fputs("|", fptr); + fputs("\t|", fptr); for (size_t i = 0; i < DOC_MARGIN; i++) { @@ -138,7 +137,7 @@ void document_page_margin(FILE *fptr, int margin /* 0 - first margin, 1 - second } if (margin == 1) - fputs("|\n", fptr); + fputs("\t|\n", fptr); } void document_print(struct document *doc, FILE *fptr) @@ -202,7 +201,7 @@ int main(int argc, char const *argv[]) document_print(doc, stdout); - doc_free(doc, row_deallocator); + doc_free(doc); return 0; } diff --git a/examples/sieve.c b/examples/sieve.c index 131f76b..12f681a 100644 --- a/examples/sieve.c +++ b/examples/sieve.c @@ -1,5 +1,5 @@ -#include #include "cmc/bitset.h" +#include CMC_CMC_BITSET_CORE(PUBLIC, HEADER, (bs, bitset)) CMC_CMC_BITSET_CORE(PUBLIC, SOURCE, (bs, bitset)) From 645b02708db8b36e32ebaf47aa81cdc7116c1f0e Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 26 Jun 2020 00:01:08 -0300 Subject: [PATCH 49/51] Create STATUS --- STATUS | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 STATUS diff --git a/STATUS b/STATUS new file mode 100644 index 0000000..0c96bd4 --- /dev/null +++ b/STATUS @@ -0,0 +1,72 @@ +Approximate completion of the library + +[ 99 ][ 99 ][ 99 ] % +[source][tests][docs] + +## - Finished + +[30][15][01] Library + +[91][45][01] CMC + [40][40][05] BitSet + [##][##][10] Deque + [80][70][00] HashBidiMap + [##][##][00] HashMap + [##][20][00] HashMultiMap + [##][20][00] HashMultiSet + [##][40][00] HashSet + [##][30][00] Heap + [##][40][00] IntervalHeap + [90][20][00] LinkedList + [90][30][00] List + [##][60][00] Queue + [00][00][00] SkipList + [80][20][00] SortedList + [95][90][00] Stack + [00][00][00] TreeBidiMap + [95][20][00] TreeMap + [00][00][00] TreeMultiMap + [00][00][00] TreeMultiSet + [95][20][00] TreeSet +[00][00][00] SAC + [00][00][00] BitSet + [00][00][00] Deque + [00][00][00] HashBidiMap + [00][00][00] HashMap + [00][00][00] HashMultiMap + [00][00][00] HashMultiSet + [00][00][00] HashSet + [00][00][00] Heap + [00][00][00] IntervalHeap + [00][00][00] LinkedList + [00][00][00] List + [00][00][00] Queue + [00][00][00] SkipList + [00][00][00] SortedList + [00][00][00] Stack + [00][00][00] TreeBidiMap + [00][00][00] TreeMap + [00][00][00] TreeMultiMap + [00][00][00] TreeMultiSet + [00][00][00] TreeSet +[00][00][00] TSC + [00][00][00] BitSet + [00][00][00] Deque + [00][00][00] HashBidiMap + [00][00][00] HashMap + [00][00][00] HashMultiMap + [00][00][00] HashMultiSet + [00][00][00] HashSet + [00][00][00] Heap + [00][00][00] IntervalHeap + [00][00][00] LinkedList + [00][00][00] List + [00][00][00] Queue + [00][00][00] SkipList + [00][00][00] SortedList + [00][00][00] Stack + [00][00][00] TreeBidiMap + [00][00][00] TreeMap + [00][00][00] TreeMultiMap + [00][00][00] TreeMultiSet + [00][00][00] TreeSet From 835caa8333f7d1bf7bab8c9e32798f3fb8465982 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 26 Jun 2020 00:01:41 -0300 Subject: [PATCH 50/51] Forwarding changes --- Makefile | 95 ---------------------------------------------- examples/example.c | 67 ++++++++++++++++++++++++++++++++ src/dev/deque.h | 0 3 files changed, 67 insertions(+), 95 deletions(-) delete mode 100644 Makefile create mode 100644 examples/example.c delete mode 100644 src/dev/deque.h diff --git a/Makefile b/Makefile deleted file mode 100644 index a1c1c2a..0000000 --- a/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -# This file was generated by a Python script -CC = gcc -CFLAGS = -std=c11 -Wall -Wextra -CFLAGS += -Wno-missing-braces -DCMC_TEST_COLOR -CVFLAGS = --coverage -O0 -g3 -INCLUDE = ./tests/include -I src - -# Runs the script to update tests, run all tests and code coverage -all: script coverage - -tests: script build - ./tests/main.exe - -# Like build but with coverage -coverage: ./tests/build/obj/cmc/bitset.o ./tests/build/obj/cmc/deque.o ./tests/build/obj/cmc/hashbidimap.o ./tests/build/obj/cmc/hashmap.o ./tests/build/obj/cmc/hashmultimap.o ./tests/build/obj/cmc/hashmultiset.o ./tests/build/obj/cmc/hashset.o ./tests/build/obj/cmc/heap.o ./tests/build/obj/cmc/intervalheap.o ./tests/build/obj/cmc/linkedlist.o ./tests/build/obj/cmc/list.o ./tests/build/obj/cmc/queue.o ./tests/build/obj/cmc/sortedlist.o ./tests/build/obj/cmc/stack.o ./tests/build/obj/cmc/treemap.o ./tests/build/obj/cmc/treeset.o ./tests/build/obj/main.o - $(CC) $^ -o ./tests/main.exe $(CFLAGS) $(CVFLAGS) - ./tests/main.exe - gcov ./tests/build/obj/main.o ./tests/build/obj/cmc/bitset.o ./tests/build/obj/cmc/deque.o ./tests/build/obj/cmc/hashbidimap.o ./tests/build/obj/cmc/hashmap.o ./tests/build/obj/cmc/hashmultimap.o ./tests/build/obj/cmc/hashmultiset.o ./tests/build/obj/cmc/hashset.o ./tests/build/obj/cmc/heap.o ./tests/build/obj/cmc/intervalheap.o ./tests/build/obj/cmc/linkedlist.o ./tests/build/obj/cmc/list.o ./tests/build/obj/cmc/queue.o ./tests/build/obj/cmc/sortedlist.o ./tests/build/obj/cmc/stack.o ./tests/build/obj/cmc/treemap.o ./tests/build/obj/cmc/treeset.o - -# Run without coverage -run: build - ./tests/main.exe - -script: - python autogen.py - -clean: - find ./tests/build -type f -delete - rm *.gcov - -# No coverage build -build: ./tests/build/obj/cmc/bitset.o ./tests/build/obj/cmc/deque.o ./tests/build/obj/cmc/hashbidimap.o ./tests/build/obj/cmc/hashmap.o ./tests/build/obj/cmc/hashmultimap.o ./tests/build/obj/cmc/hashmultiset.o ./tests/build/obj/cmc/hashset.o ./tests/build/obj/cmc/heap.o ./tests/build/obj/cmc/intervalheap.o ./tests/build/obj/cmc/linkedlist.o ./tests/build/obj/cmc/list.o ./tests/build/obj/cmc/queue.o ./tests/build/obj/cmc/sortedlist.o ./tests/build/obj/cmc/stack.o ./tests/build/obj/cmc/treemap.o ./tests/build/obj/cmc/treeset.o ./tests/build/obj/main.o - $(CC) $^ -o ./tests/main.exe $(CFLAGS) - -./tests/build/obj/main.o: ./tests/main.c - $(CC) -c $^ -o $@ -I $(INCLUDE) $(CFLAGS) - -fmt_all: fmt_src fmt_tests - -fmt_src: FORCE - find ./src/ -iname *.h | xargs clang-format --style=file --verbose -i - -fmt_tests: FORCE - find ./tests/ -iname *.c -o -iname *.h | xargs clang-format --style=file --verbose -i - -.PHONY FORCE: - - -./tests/build/obj/cmc/bitset.o: ./tests/src/cmc/bitset.c ./tests/include/cmc/bitset.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/deque.o: ./tests/src/cmc/deque.c ./tests/include/cmc/deque.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/hashbidimap.o: ./tests/src/cmc/hashbidimap.c ./tests/include/cmc/hashbidimap.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/hashmap.o: ./tests/src/cmc/hashmap.c ./tests/include/cmc/hashmap.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/hashmultimap.o: ./tests/src/cmc/hashmultimap.c ./tests/include/cmc/hashmultimap.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/hashmultiset.o: ./tests/src/cmc/hashmultiset.c ./tests/include/cmc/hashmultiset.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/hashset.o: ./tests/src/cmc/hashset.c ./tests/include/cmc/hashset.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/heap.o: ./tests/src/cmc/heap.c ./tests/include/cmc/heap.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/intervalheap.o: ./tests/src/cmc/intervalheap.c ./tests/include/cmc/intervalheap.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/linkedlist.o: ./tests/src/cmc/linkedlist.c ./tests/include/cmc/linkedlist.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/list.o: ./tests/src/cmc/list.c ./tests/include/cmc/list.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/queue.o: ./tests/src/cmc/queue.c ./tests/include/cmc/queue.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/sortedlist.o: ./tests/src/cmc/sortedlist.c ./tests/include/cmc/sortedlist.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/stack.o: ./tests/src/cmc/stack.c ./tests/include/cmc/stack.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/treemap.o: ./tests/src/cmc/treemap.c ./tests/include/cmc/treemap.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) - -./tests/build/obj/cmc/treeset.o: ./tests/src/cmc/treeset.c ./tests/include/cmc/treeset.h - $(CC) -c $< -o $@ -I $(INCLUDE) $(CFLAGS) $(CVFLAGS) diff --git a/examples/example.c b/examples/example.c new file mode 100644 index 0000000..527d78d --- /dev/null +++ b/examples/example.c @@ -0,0 +1,67 @@ +// This is the master header. This will include every feature of the library. +// This comes with many helper macros (high level API) and utility functions. +#include "macro_collections.h" + +// A PARAM is a standard way to pass required parameters to the lower level API. +// It is a tuple of form (PFX, SNAME, SIZE, K, V). In this case, not all of them +// are used, so we can leave them empty. We are creating a list of value int. +#define MY_LIST_PARAMS (intl, int_list, , , int) + +// High level API. Generate a LIST from the CMC library with the STR extension +// using our previously defined PARAMs. Every collections has a CORE part that +// needs to be generated first. Then, we can add other parts after. This macro +// does all of that for us. The STR part will provide us with a function that +// will be used later. +C_MACRO_COLLECTIONS_GEN(CMC, LIST, MY_LIST_PARAMS, (STR)) + +int main(void) +{ + // Our list type is defined by SNAME and all functions are prefixed by PFX + // (PFX can also be thought as the function's namespace). Also, nodes, + // entries, iterators and other structures are prefixed by SNAME. So PFX is + // for functions and SNAME is for structs, where the main one is simply + // 'struct SNAME'. + // To initialize a list we need to pass in an initial capacity and something + // that is called a function table for the V type. + // This function table is a struct with methods that will extract some + // (sometimes) necessary behaviour from your custom data type. Things like + // hash, comparison and printing. A list doesn't require any of these + // functions. That is, the CORE module doesn't use any of them. + // But since we are using the STR module, we will need to define the 'str' + // function. luckily, for the 'int' type, the library already provides such + // function (cmc_i32_str), provided by the /utl/futils.h header file. + struct int_list *list = intl_new(32, &(struct int_list_fval){ .str = cmc_i32_str, NULL }); + + // Check if the list was successfully initialized. It could fail if the + // initial capacity is too big or if 'struct int_list_fval *' is NULL, + // because every data structure must have a valid function table. + if (!list) + return 1; + + // Add some items to the list. The CMC data structures are all dynamically + // sized. So there can be as many items as you want as long as you have + // enough memory. + for (int i = 0; i < 100; i++) + { + // Try to add an element to the list. If it fails you can check what + // caused it by getting its flag. + if (!intl_push_back(list, i)) + { + enum cmc_flags flag = intl_flag(list); + // Use cmc_flags_to_str to map the enum error to a string. + fprintf(stderr, "%s : push_back failed\n", cmc_flags_to_str[flag]); + } + } + + // Now we will use the STR module, the _print() function. This is where the + // '.str' from the function table comes into play. If we haven't defined it, + // the program would've crashed. We also need to define to which file we + // will be printing the list's content. In this case, the terminal. Also, + // some strings need to be defined. They will be printed: before all elements, + // between each one, and after all elements. This is very usefull and can + // print a data structure very nicely. + intl_print(list, stdout, "[ ", ", ", " ]\n"); + + // Free all of its resources + intl_free(list); +} diff --git a/src/dev/deque.h b/src/dev/deque.h deleted file mode 100644 index e69de29..0000000 From b51efa5c45310fb0e69754861f07b6b7973687bf Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 26 Jun 2020 00:02:13 -0300 Subject: [PATCH 51/51] v0.24.0 --- .github/workflows/test_suit.yml | 8 +- CHANGELOG | 2 +- README.md | 288 +++++++++++++++----------------- TODO | 64 +++++-- 4 files changed, 195 insertions(+), 167 deletions(-) diff --git a/.github/workflows/test_suit.yml b/.github/workflows/test_suit.yml index c51bb75..e60a5df 100644 --- a/.github/workflows/test_suit.yml +++ b/.github/workflows/test_suit.yml @@ -10,8 +10,8 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup Environment - run: sudo apt install make valgrind gcc + run: sudo apt install make valgrind gcc python - name: Test Suite - run: make -C ./tests/main nocov - - name: Valgrind Test - run: make -C ./tests/main valgrind + run: python autogen.py -e -b -r -nf + # - name: Valgrind Test + # run: make -C ./tests/main valgrind diff --git a/CHANGELOG b/CHANGELOG index b125b5b..120734c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,7 +10,7 @@ ./cor/alloc.h ./cor/callbacks.h ./cor/heap.h - Complete rework of tests and code coverage + Complete rework of tests and code coverage using autogen.py Removed cmc_flags, where now every flag is an enum (CMC_FLAGS_OK, CMC_FLAGS_ERROR, etc) Different include guards New way to generate code using PARAM diff --git a/README.md b/README.md index efd7eec..239129e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@

License - Version + Version travis-ci codecov test_suit @@ -21,61 +21,118 @@ ## Table of Contents -* Installation -* Usage -* Contributing -* License -* Features +* [Installation](#installation) +* [Contributing](#contributing) +* [Usage](#usage) +* [Features](#features) +* [Project Structure](#project-structure) +* [Available Collections](#available-collections) +* [Other Features](#other-features) +* [Design Decisions](#design-decisions) +* [What to use](#what-to-use) +* [Code Review](#code-review) ## Installation No installation is required. The entire library is made of header files and can be directly included into your project. +## Contributing + +There is a lot to be done. You can check the `TODO` file in the root of the repository or the issues in the github page. Also, tests and documentation are in constant development. Also check out the `STATUS` file for the status on the development of the library. + ## Usage The header `macro_collections.h` includes every feature from the library and comes with higher level APIs that help you generate collections from specific sub-libraries with specific extensions. +Below is a minimal example that makes use of some core functionalities. And a lot of explanation too! + ```c -// WIP +// This is the master header. This will include every feature of the library. +// This comes with many helper macros (high level API) and utility functions. #include "macro_collections.h" // A PARAM is a standard way to pass required parameters to the lower level API. // It is a tuple of form (PFX, SNAME, SIZE, K, V). In this case, not all of them -// are used, so we can leave them empty. -#define MY_LIST_PARAMS (si32, stacki32, , , int32_t) +// are used, so we can leave them empty. We are creating a list of value int. +#define MY_LIST_PARAMS (intl, int_list, , , int) // High level API. Generate a LIST from the CMC library with the STR extension -C_MACRO_COLLECTIONS_GEN(PUBLIC, CMC, LIST, MY_LIST_PARAMS, (STR)) - -bool int_str(FILE *fptr, int val) -{ - return 0 <= fprintf(fptr, "%d", val); -} +// using our previously defined PARAMs. Every collections has a CORE part that +// needs to be generated first. Then, we can add other parts after. This macro +// does all of that for us. The STR part will provide us with a function that +// will be used later. +C_MACRO_COLLECTIONS_GEN(CMC, LIST, MY_LIST_PARAMS, (STR)) int main(void) { - struct stack_int *stack = sint_new(100, &(struct stack_int_fval) { .str = int_str }); + // Our list type is defined by SNAME and all functions are prefixed by PFX + // (PFX can also be thought as the function's namespace). Also, nodes, + // entries, iterators and other structures are prefixed by SNAME. So PFX is + // for functions and SNAME is for structs, where the main one is simply + // 'struct SNAME'. + // To initialize a list we need to pass in an initial capacity and something + // that is called a function table for the V type. + // This function table is a struct with methods that will extract some + // (sometimes) necessary behaviour from your custom data type. Things like + // hash, comparison and printing. A list doesn't require any of these + // functions. That is, the CORE module doesn't use any of them. + // But since we are using the STR module, we will need to define the 'str' + // function. luckily, for the 'int' type, the library already provides such + // function (cmc_i32_str), provided by the /utl/futils.h header file. + struct int_list *list = intl_new(32, &(struct int_list_fval){ .str = cmc_i32_str, NULL }); - si32_free(stack); + // Check if the list was successfully initialized. It could fail if the + // initial capacity is too big or if 'struct int_list_fval *' is NULL, + // because every data structure must have a valid function table. + if (!list) + return 1; + + // Add some items to the list. The CMC data structures are all dynamically + // sized. So there can be as many items as you want as long as you have + // enough memory. + for (int i = 0; i < 100; i++) + { + // Try to add an element to the list. If it fails you can check what + // caused it by getting its flag. + if (!intl_push_back(list, i)) + { + enum cmc_flags flag = intl_flag(list); + // Use cmc_flags_to_str to map the enum error to a string. + fprintf(stderr, "%s : push_back failed\n", cmc_flags_to_str[flag]); + } + } + + // Now we will use the STR module, the _print() function. This is where the + // '.str' from the function table comes into play. If we haven't defined it, + // the program would've crashed. We also need to define to which file we + // will be printing the list's content. In this case, the terminal. Also, + // some strings need to be defined. They will be printed: before all elements, + // between each one, and after all elements. This is very usefull and can + // print a data structure very nicely. + intl_print(list, stdout, "[ ", ", ", " ]\n"); + + // You should see a nicely printed list in your terminal. + + // Free all of its resources + intl_free(list); } - ``` -## Contributing +Now all you have to do is to compile the source code with `-I /path/to/library/src`. There is no required installation or pre-compilation. ## Features The C Macro Collections library is organized into many other sub-libraries. The following table is a quick overview. -| Library | Name | Description | -| :-----: | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| CMC | The main C Macro Collections | The main library with variably-sized collections | -| COR | Core | Core functionalities used by more than one collection, usually from different sub-libraries | -| EXT | Extensions | Extension to collections from CMC, SAC and TSC libraries | -| INT | Integrations | Macros that facilitate the creation of code that involves more than one type of collection, e.g. transforming a set to a list | -| SAC | Statically Allocated Collections | Collections with a fixed sized array that don't use any heap allocation | -| TSC | Thread-Safe Collections | Collections that allow multiple operations from multiple threads | -| UTL | Utilities | Utilities for the library | +| Library | Name | Description | +| :-----: | -------------------------------- | ------------------------------------------------------------------------------------------- | +| CMC | Macro Collections | The main library with dynamically-sized collections | +| COR | Core | Core functionalities used by more than one collection, usually from different sub-libraries | +| EXT | Extensions | Extension to collections from CMC, SAC and TSC libraries | +| INT | Integrations | Macros that facilitate the creation of code that involves more than one type of collection | +| SAC | Statically Allocated Collections | Collections with a fixed sized array that don't use any heap allocation | +| TSC | Thread-Safe Collections | Collections that allow multiple operations from multiple threads | +| UTL | Utilities | General utilities | Every macro that generates code for a certain collection can be found with the following template. Some exceptions exist as certain collections don't have or can't have some features. One big example is the `UTL` library, which does not follow this pattern. @@ -83,22 +140,14 @@ Every macro that generates code for a certain collection can be found with the f macro_name := CMC_[ lib ]_[ collection ]_[ part ]_[ file ] lib := CMC | COR | DEV | EXT | INT | SAC | TSC -collection := BITSET | DEQUE | HASHBIDIMAP | HASHMAP | HASHMULTIMAP | HASHMULTISET | HASHSET | HEAP | INTERVALHEAP | LINKEDLIST | LIST | QUEUE | SORTEDLIST | STACK | TREEBIDIMAP | TREEMAP | TREEMULTIMAP | TREEMULTISET | TREESET -part := CORE | ITER | INIT | SETF | NODE ... +collection := BITSET | DEQUE | HASHBIDIMAP | ... | TREEMULTISET | TREESET +part := CORE | ITER | INIT | ... | SETF | NODE file := HEADER | SOURCE ``` __Some `collection`s might not be present in a certain `lib`. Check the documentation.__ -Every macro is suffixed by `CMC` and each section is separated by an underscore (`_`). The first section is the library (`lib`). The second is the collection name in all uppercase. Then the `part` (or which feature from it) that you wish to generate. And last, if it is code that should belong to a header file or code that should belong to a source file. - -* Project Structure -* Available Collections -* Features -* Overall To-Do -* Design Decisions -* What to use -* How to use +Every macro is suffixed by `CMC` and each section is separated by an underscore (`_`). The first section is the library (`lib`). The second is the collection name in all uppercase. Then the `part` (or which module) that you wish to generate. And last, if it is code that should belong to a header file or code that should belong to a source file. ## Project Structure @@ -109,53 +158,46 @@ Every macro is suffixed by `CMC` and each section is separated by an underscore * __src__ - All headers part of the C Macro Collections Library * __cmc__ - The main C Macro Collections Library * __cor__ - Core includes in the C Macro Collections Library - * __dev__ - The main C Macro Collections Library for development (containing logging) - * __sac__ - Statically Allocated Collections - * __utl__ - Utility like ForEach macros, logging, etc + * __ext__ - Extensions to the CMC, SAC and TSC collections + * __int__ - Integrations between Collections + * __sac__ - Statically Allocated Collections + * __tsc__ - Thread Safe Collections + * __utl__ - Utilities like ForEach macros, logging, etc * __macro\_collections.h__ - Master header containing all collections and utilities * __tests__ - Where all tests are hosted ## Available Collections -* Linear Collections - * List, LinkedList, Deque, Stack, Queue, SortedList -* Sets - * HashSet, TreeSet, HashMultiSet -* Maps - * HashMap, TreeMap, HashMultiMap -* Bidirectional Maps - * HashBidiMap -* Heaps - * Heap, IntervalHeap -* WIP - * BitSet, Matrix, TreeBidiMap, TreeMultiMap, TreeMultiSet +Check out the STATUS file at the root of the project for more information. __The following table is an overview of all the currently available or upcoming data structures__: -| Collection | Abstract Data Type | Data Structure | Details | -| :--------------------------------: | :---------------------------------: | :-----------------------------: | :-----------------------------------: | -| BitSet
_bitset.h_ | Set | Dynamic Array | A set of bits that can be individually modified and queried, each identified by a bit index | -| Deque
_deque.h_ | Double-Ended Queue | Dynamic Circular Array | A circular array that allows `push` and `pop` on both ends (only) at constant time | -| HashBidiMap
_hashbidimap.h_ | Bidirectional Map | Two Hashtables | A bijection between two sets of unique keys and unique values `K <-> V` using two hashtables | -| HashMap
_hashmap.h_ | Map | Flat Hashtable | A unique set of keys associated with a value `K -> V` with constant time look up using a hashtable with open addressing and robin hood hashing | -| HashMultiMap
_hashmultimap.h_ | Multimap | Hashtable | A mapping of multiple keys with one node per key using a hashtable with separate chaining | -| HashMultiSet
_hashmultiset.h_ | Multiset | Flat Hashtable | A mapping of a value and its multiplicity using a hashtable with open addressing and robin hood hashing | -| HashSet
_hashset.h_ | Set | Flat Hashtable | A unique set of values with constant time look up using a hashtable with open addressing and robin hood hashing | -| Heap
_heap.h_ | Priority Queue | Dynamic Array | A binary heap as a dynamic array as an implicit data structure | -| IntervalHeap
_intervalheap.h_ | Double-Ended Priority Queue | Custom Dynamic Array | A dynamic array of nodes, each hosting one value from the MinHeap and one from the MaxHeap | -| LinkedList
_linkedlist.h_ | List | Doubly-Linked List | A default doubly-linked list | -| List
_list.h_ | List | Dynamic Array | A dynamic array with `push` and `pop` anywhere on the array | -| Matrix
_WIP_ | Regular Matrix | Dynamic Array of Dynamic Arrays | A regular matrix with arbitrary rows and columns | -| Queue
_queue.h_ | FIFO | Dynamic Circular Array | A queue using a circular array with `enqueue` at the `back` index and `dequeue` at the `front` index | -| SortedList
_sortedlist.h_ | Sorted List | Sorted Dynamic Array | A lazily sorted dynamic array that is sorted only when necessary | -| Stack
_stack.h_ | FILO | Dynamic Array | A stack with push and pop at the end of a dynamic array | -| TreeBidiMap
_WIP_ | Sorted Bidirectional Map | Two AVL Trees | A sorted bijection between two sets of unique keys and unique values `K <-> V` using two AVL trees | -| TreeMap
_treemap.h_ | Sorted Map | AVL Tree | A unique set of keys associated with a value `K -> V` using an AVL tree with `log(n)` look up and sorted iteration | -| TreeMultiMap
_WIP_ | Sorted Multimap | AVL Tree | A sorted mapping of multiple keys with one node per key using an AVL Tree of linked-lists | -| TreeMultiSet
_WIP_ | Sorted Multiset | AVL Tree | A sorted mapping of a value and its multiplicity using an AVL tree | -| TreeSet
_treeset.h_ | Sorted Set | AVL Tree | A unique set of keys using an AVL tree with `log(n)` look up and sorted iteration | +| Collection | Abstract Data Type | Data Structure | Details | +| :--------------------------------: | :---------------------------------: | :-----------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------: | +| BitSet
_bitset.h_ | Set | Dynamic Array | A set of bits that can be individually modified and queried, each identified by a bit index | +| Deque
_deque.h_ | Double-Ended Queue | Dynamic Circular Array | A circular array that allows `push` and `pop` on both ends (only) at constant time | +| HashBidiMap
_hashbidimap.h_ | Bidirectional Map | Two Hashtables | A bijection between two sets of unique keys and unique values `K <-> V` using two hashtables | +| HashMap
_hashmap.h_ | Map | Flat Hashtable | A unique set of keys associated with a value `K -> V` with constant time look up using a hashtable with open addressing and robin hood hashing | +| HashMultiMap
_hashmultimap.h_ | Multimap | Hashtable | A mapping of multiple keys with one node per key using a hashtable with separate chaining | +| HashMultiSet
_hashmultiset.h_ | Multiset | Flat Hashtable | A mapping of a value and its multiplicity using a hashtable with open addressing and robin hood hashing | +| HashSet
_hashset.h_ | Set | Flat Hashtable | A unique set of values with constant time look up using a hashtable with open addressing and robin hood hashing | +| Heap
_heap.h_ | Priority Queue | Dynamic Array | A binary heap as a dynamic array as an implicit data structure | +| IntervalHeap
_intervalheap.h_ | Double-Ended Priority Queue | Custom Dynamic Array | A dynamic array of nodes, each hosting one value from the MinHeap and one from the MaxHeap | +| LinkedList
_linkedlist.h_ | List | Doubly-Linked List | A default doubly-linked list | +| List
_list.h_ | List | Dynamic Array | A dynamic array with `push` and `pop` anywhere on the array | +| Queue
_queue.h_ | FIFO | Dynamic Circular Array | A queue using a circular array with `enqueue` at the `back` index and `dequeue` at the `front` index | +| SkipList
_WIP_ | Sorted List | Skip List | A sorted Linked List with average O(log n) search, insertion and deletion complexity | +| SortedList
_sortedlist.h_ | Sorted List | Sorted Dynamic Array | A lazily sorted dynamic array that is sorted only when necessary | +| Stack
_stack.h_ | FILO | Dynamic Array | A stack with push and pop at the end of a dynamic array | +| TreeBidiMap
_WIP_ | Sorted Bidirectional Map | Two AVL Trees | A sorted bijection between two sets of unique keys and unique values `K <-> V` using two AVL trees | +| TreeMap
_treemap.h_ | Sorted Map | AVL Tree | A unique set of keys associated with a value `K -> V` using an AVL tree with `log(n)` look up and sorted iteration | +| TreeMultiMap
_WIP_ | Sorted Multimap | AVL Tree | A sorted mapping of multiple keys with one node per key using an AVL Tree of linked-lists | +| TreeMultiSet
_WIP_ | Sorted Multiset | AVL Tree | A sorted mapping of a value and its multiplicity using an AVL tree | +| TreeSet
_treeset.h_ | Sorted Set | AVL Tree | A unique set of keys using an AVL tree with `log(n)` look up and sorted iteration | -## Features +## Other Features + +These are some features within the library that are implemented by all collections. ### Two-way iterators @@ -207,8 +249,8 @@ A priority function works much like the comparator function except that it compa The following table shows which functions are required, optional or never used for each Collection: -| Collection | CMP | CPY | STR | FREE | HASH | PRI | -| ---------- | :-: | :-: | :-: | :--: | :--: | :-: | +| Collection | CMP | CPY | STR | FREE | HASH | PRI | +| ------------ | :------------------------------------------------------: | :------------------------------------------------------: | :------------------------------------------------------: | :------------------------------------------------------: | :------------------------------------------------------: | :------------------------------------------------------: | | Deque | ![#9f3b94](https://placehold.it/20/9f3b94/000000?text=+) | ![#9f3b94](https://placehold.it/20/9f3b94/000000?text=+) | ![#497edd](https://placehold.it/20/497edd/000000?text=+) | ![#00d3eb](https://placehold.it/20/00d3eb/000000?text=+) | ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | | HashMap | ![#b82b28](https://placehold.it/20/b82b28/000000?text=+) | ![#9f3b94](https://placehold.it/20/9f3b94/000000?text=+) | ![#497edd](https://placehold.it/20/497edd/000000?text=+) | ![#00d3eb](https://placehold.it/20/00d3eb/000000?text=+) | ![#b82b28](https://placehold.it/20/b82b28/000000?text=+) | ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | | HashBidiMap | ![#b82b28](https://placehold.it/20/b82b28/000000?text=+) | ![#9f3b94](https://placehold.it/20/9f3b94/000000?text=+) | ![#497edd](https://placehold.it/20/497edd/000000?text=+) | ![#00d3eb](https://placehold.it/20/00d3eb/000000?text=+) | ![#b82b28](https://placehold.it/20/b82b28/000000?text=+) | ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | @@ -225,23 +267,13 @@ The following table shows which functions are required, optional or never used f | TreeMap | ![#b82b28](https://placehold.it/20/b82b28/000000?text=+) | ![#9f3b94](https://placehold.it/20/9f3b94/000000?text=+) | ![#497edd](https://placehold.it/20/497edd/000000?text=+) | ![#00d3eb](https://placehold.it/20/00d3eb/000000?text=+) | ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | | TreeSet | ![#b82b28](https://placehold.it/20/b82b28/000000?text=+) | ![#9f3b94](https://placehold.it/20/9f3b94/000000?text=+) | ![#497edd](https://placehold.it/20/497edd/000000?text=+) | ![#00d3eb](https://placehold.it/20/00d3eb/000000?text=+) | ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | -| Color | Label | -| :---: | ----- | -| ![#b82b28](https://placehold.it/20/b82b28/000000?text=+) | Required for basic functionality. | -| ![#9f3b94](https://placehold.it/20/9f3b94/000000?text=+) | Required for specific functions. | +| Color | Label | +| :------------------------------------------------------: | ----------------------------------------- | +| ![#b82b28](https://placehold.it/20/b82b28/000000?text=+) | Required for basic functionality. | +| ![#9f3b94](https://placehold.it/20/9f3b94/000000?text=+) | Required for specific functions. | | ![#497edd](https://placehold.it/20/497edd/000000?text=+) | Required for non-core specific functions. | -| ![#00d3eb](https://placehold.it/20/00d3eb/000000?text=+) | Optional. | -| ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | Not Used. | - -## Overall To-Do - -In the long term, these are the steps left for the completion of this library: - -* Complete the implementation of all the functions in the scope of the TODO file for the main collections; -* Reorganize and complete all tests for the `cmc` collections; -* Make an exact copy of all collections to `dev` with many logging utility, for them to be used under development; -* Port all of these collections to be statically allocated and be part of the `sac` library; -* Complete all tests for `sac`. +| ![#00d3eb](https://placehold.it/20/00d3eb/000000?text=+) | Optional. | +| ![#2ef625](https://placehold.it/20/2ef625/000000?text=+) | Not Used. | ## Design Decisions @@ -269,6 +301,8 @@ Modifying a collection will possibly invalidate all iterators currently initiali ## What to use +(Outdated) + The following table shows how each collection is implemented and how well they do when using as common [abstract data types](https://en.wikipedia.org/wiki/Abstract_data_type). * **Ideal** - The collection implements correctly the abstract data type; @@ -281,62 +315,14 @@ The following table shows how each collection is implemented and how well they d ![AverageColor](https://img.shields.io/badge/Not_Ideal_Implementation-%2363a4ff.svg) ![BadColor](https://img.shields.io/badge/Bad_Implementation-%23ff6659.svg) -## How to use +## Code Review -To generate the collection, all you need to do is to include the necessary header files. You can include the containers you want to use individually or you can include the master header, `macro_collections.h`, that comes with the entire C-Macro-Collections library. +Check out some code reviews that covers some parts the project. Most of them were posted a long time ago and are probably outdated. -### Macros - -> Note here that `SNAME` represents the uppercase name of the collection. - -Every collection is separated by two parts: - -* `HEADER` - Contains all struct definitions and function definitions. -* `SOURCE` - Contains all function implementations. - -All collections have three main macros: - -* `CMC_GENERATE_SNAME` - Generates `CMC_GENERATE_SNAME_HEADER` and `CMC_GENERATE_SNAME_SOURCE`. - -Or you can generate each part individually: - -* `CMC_GENERATE_SNAME_HEADER` - Generates all struct definitions and function definitions. -* `CMC_GENERATE_SNAME_SOURCE` - Generates all function implementations. - -### Parameters - -When including `macro_collections.h` in your source code you gain access to a macro called `CMC_COLLECTION_GENERATE` with the following parameters: - -* __C__ - Container name in uppercase (*BIDIMAP*, *DEQUE*, *HASHMAP*, *HASHSET*, *HEAP*, *INTERVALHEAP*, *LINKEDLIST*, *LIST*, *MULTIMAP*, *MULTISET*, *QUEUE*, *SORTEDLIST*, *STACK*, *TREEMAP*, *TREESET*). -* __PFX__ - Functions prefix or namespace. -* __SNAME__ - Structure name (`struct SNAME`). -* __K__ - Key type. Only used in *HASHMAP*, *TREEMAP*, *MULTIMAP* and *BIDIMAP*; ignored by others. -* __V__ - Value type. Primary type for most collections, or value to be mapped by *HASHMAP*, *TREEMAP*, *MULTIMAP* and *BIDIMAP*. - -**In fact, all macros follow this pattern.** So whenever you see a macro with a bunch of parameters and you don't know what they are, you can check out the above list. - -### For Each - -There are 2 for-each macros: - -* `CMC_FOREACH` - Starts at the start of the collection towards the end. -* `CMC_FOREACH_REV` - Starts at the end of the collection towards the start. - -* __PFX__ - Functions prefix or namespace. -* __SNAME__ - Structure name. -* __TARGET__ - The variable name of the collection you wish to iterate over. -* __ITERNAME__ - Iterator variable name. - -For `CMC_FOREACH` and `CMC_FOREACH_REV` you will be able to name the iterator variable through the __ITERNAME__ parameter. - -


- -Check out some code reviews that covers some parts the project: - -| About | Link | -|-------|--------| -| Unit Test *./utl/test.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=222954)](http://codereview.stackexchange.com/q/222954/178948) | +| About | Link | +| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| Unit Test *./utl/test.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=222954)](http://codereview.stackexchange.com/q/222954/178948) | | Interval Heap *./cmc/intervalheap.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=223595)](http://codereview.stackexchange.com/q/223595/178948) | -| Hash Set *./cmc/hashset.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=217333)](http://codereview.stackexchange.com/q/217333/178948) | -| Linked List *./cmc/linkedlist.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=216737)](http://codereview.stackexchange.com/q/216737/178948) | -| Others | [![Code Review](http://www.zomis.net/codereview/shield/?qid=213553)](http://codereview.stackexchange.com/q/213553/178948) | +| Hash Set *./cmc/hashset.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=217333)](http://codereview.stackexchange.com/q/217333/178948) | +| Linked List *./cmc/linkedlist.h* | [![Code Review](http://www.zomis.net/codereview/shield/?qid=216737)](http://codereview.stackexchange.com/q/216737/178948) | +| Others | [![Code Review](http://www.zomis.net/codereview/shield/?qid=213553)](http://codereview.stackexchange.com/q/213553/178948) | diff --git a/TODO b/TODO index b732cc3..bf2effd 100644 --- a/TODO +++ b/TODO @@ -1,19 +1,57 @@ TODO +Patch - Changes that can be released by a patch version +Minor - Changes that require a bit more time than a simple patch +Major - 1.0.0 version or breaking changes + +The library follows https://semver.org/ +Check out CHANGELOG + [/] - In Progress [X] - Finished -#!! High Priority ---------------------------------------------------------------------------------- -[/] Tests -[/] Documentation +#!! Next Patch ----------------------------------------------------------------- -#!! Medium Priority -------------------------------------------------------------------------------- +[ ] Fix BitSet, using capacity vs. counter +[ ] #12 - Fix the collections that depend on ITER + +#!! Major ---------------------------------------------------------------------- + +[ ] Stabilize the library +[ ] Add INT library +[ ] Add SAC library +[ ] Add TSC library +[ ] Separate inner Data Structure implementation from the Collection's one +[ ] CMC_NAMES - Full customization of function names (see CMC_CAMEL_CASE) +[\] Tests +[\] Documentation + + +#!! Minor ---------------------------------------------------------------------- + +[ ] #13 - Properly implement HashBidiMap iterator +[ ] #10 - Fix Benchmarks and Examples +[ ] More SortedList functions +[ ] BidiMap's _is_mapping() to check if a mapping K <=> V exists +[ ] New asserts - _array_int(), _array_not_in() and str +[ ] Add Stack's _peek() and _top() (get by value, get by pointer) +[ ] CMC_TIMED for timed blocks +[ ] _iter_at() iterator + + +#!! Patch ---------------------------------------------------------------------- + +[ ] MultiSets replace existing value with the new added one +[ ] Fix PUBLIC and PRIVATE incompatibility between CMC and EXT + + +#!! Considerations ------------------------------------------------------------- + +[ ] rand.h utility +[ ] Redo `while (true)` in hashtables' _insert() [ ] Add to_array and from_array functions - -#!! Being Considered ------------------------------------------------------------------------------- - [ ] Serialization [ ] save {all} [ ] load {all} @@ -22,12 +60,14 @@ TODO [ ] Zip Iterators [ ] Consumer Iterators -#!! Optimizations ---------------------------------------------------------------------------------- -[ ] Use binary search to find optimum hashtable prime size inside impl_calculate_size -[ ] Optimize certain loops that use iterators that can simply use a normal loop +#!! Optimizations -------------------------------------------------------------- -#!! Done ------------------------------------------------------------------------------------------- +[ ] Use binary search to find optimum hashtable prime size inside + impl_calculate_size + + +#!! Done ----------------------------------------------------------------------- [X] Remove PUBLIC and PRIVATE [X] Utility @@ -62,3 +102,5 @@ TODO [X] Callback utility on_create, on_read, on_update, on_delete, on_resize [X] Replace IntervalHeap node by a simple buffer of two pointers (V (*buffer)[2]) +[X] PUBLIC and PRIVATE is back (opaque data structures) +[X] Add EXT library