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__ */