From aa033b03160443ffe1f9fd55e1a96c7a65adfeb7 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Thu, 4 Jun 2020 17:20:47 -0300 Subject: [PATCH] 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__ */