From 6308936e65accb69fb76a0d6edd12e4f7b7f2e04 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 26 Jun 2020 16:12:53 -0300 Subject: [PATCH 01/20] HashMultiMap no longer depends on ITER --- .../C++ Comparison/hashtable/hashmultimap.c | 3 +- src/cmc/bitset.h | 10 +- src/cmc/hashmap.h | 8 +- src/cmc/hashmultimap.h | 160 ++++++++++-------- src/cmc/hashmultiset.h | 4 +- src/cmc/hashset.h | 4 +- src/ext/cmc/treeset.h | 1 - tests/src/cmc/hashmultimap.c | 130 ++++++++------ tests/unt/cmc/hashmultimap.h | 97 +++++++++++ 9 files changed, 278 insertions(+), 139 deletions(-) diff --git a/benchmarks/C++ Comparison/hashtable/hashmultimap.c b/benchmarks/C++ Comparison/hashtable/hashmultimap.c index 2bac19a..4f25db7 100644 --- a/benchmarks/C++ Comparison/hashtable/hashmultimap.c +++ b/benchmarks/C++ Comparison/hashtable/hashmultimap.c @@ -8,7 +8,8 @@ #include "../../util/twister.c" -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , uint64_t, uint64_t)) +CMC_CMC_HASHMULTIMAP_CORE(PUBLIC, HEADER, (hmm, hashmultimap, , uint64_t, uint64_t)) +CMC_CMC_HASHMULTIMAP_CORE(PUBLIC, SOURCE, (hmm, hashmultimap, , uint64_t, uint64_t)) int cmp(uint64_t a, uint64_t b) { diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index 796d016..4e2ef04 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -86,10 +86,10 @@ /* Current array capacity */ \ size_t capacity; \ \ - /* Currently used bits */\ - /* This should always be true: */\ - /* capacity - count < sizeof(cmc_bitset_word) * CHAR_BIT */\ - size_t count;\ + /* Currently used bits */ \ + /* This should always be true: */ \ + /* capacity - count < sizeof(cmc_bitset_word) * CHAR_BIT */ \ + size_t count; \ \ /* Flags indicating errors or success */ \ int flag; \ @@ -156,7 +156,7 @@ /* Iterator Initialization */ \ /* Iterator State */ \ /* Iterator Movement */ \ - /* Iterator Access */ \ + /* Iterator Access */ /* ------------------------------------------------------------------------- * Source diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 0406261..587370b 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -461,8 +461,8 @@ return false; \ } \ \ - K max_key = (K) { 0 }; \ - V max_val = (V) { 0 }; \ + K max_key = (K){ 0 }; \ + V max_val = (V){ 0 }; \ size_t first = 0; \ \ for (; first < _map_->capacity; first++) \ @@ -505,8 +505,8 @@ return false; \ } \ \ - K min_key = (K) { 0 }; \ - V min_val = (V) { 0 }; \ + K min_key = (K){ 0 }; \ + V min_val = (V){ 0 }; \ size_t first = 0; \ \ for (; first < _map_->capacity; first++) \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index 053f55f..b1dbd55 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -300,7 +300,7 @@ { \ struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ \ - while (scan != NULL) \ + while (scan) \ { \ struct CMC_DEF_ENTRY(SNAME) *next = scan->next; \ \ @@ -329,7 +329,7 @@ { \ struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[index][0]; \ \ - if (scan != NULL) \ + if (scan) \ { \ if (scan->next == NULL && scan->prev == NULL) \ { \ @@ -342,7 +342,7 @@ } \ else \ { \ - while (scan != NULL) \ + while (scan) \ { \ struct CMC_DEF_ENTRY(SNAME) *tmp = scan; \ \ @@ -481,7 +481,7 @@ \ size_t index = 0; \ \ - while (entry != NULL) \ + while (entry) \ { \ if (_map_->f_key->cmp(entry->key, key) == 0) \ { \ @@ -543,7 +543,7 @@ { \ bool found = false; \ \ - while (entry != NULL) \ + while (entry) \ { \ if (_map_->f_key->cmp(entry->key, key) == 0) \ { \ @@ -552,9 +552,9 @@ if (*tail == entry) \ *tail = entry->prev; \ \ - if (entry->prev != NULL) \ + if (entry->prev) \ entry->prev->next = entry->next; \ - if (entry->next != NULL) \ + if (entry->next) \ entry->next->prev = entry->prev; \ \ if (out_value) \ @@ -639,7 +639,7 @@ } \ else \ { \ - while (entry != NULL) \ + while (entry) \ { \ if (_map_->f_key->cmp(entry->key, key) == 0) \ { \ @@ -650,9 +650,9 @@ \ struct CMC_DEF_ENTRY(SNAME) *next = entry->next; \ \ - if (entry->prev != NULL) \ + if (entry->prev) \ entry->prev->next = entry->next; \ - if (entry->next != NULL) \ + if (entry->next) \ entry->next->prev = entry->prev; \ \ if (out_values) \ @@ -684,27 +684,30 @@ return false; \ } \ \ - K max_key = (K) { 0 }; \ - V max_val = (V) { 0 }; \ + bool first = true; \ + K max_key = (K){ 0 }; \ + V max_val = (V){ 0 }; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ -\ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ - K result_key = CMC_(PFX, _iter_key)(&iter); \ - V result_value = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ \ - if (index == 0) \ + while (scan) \ { \ - 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 (first) \ + { \ + max_key = scan->key; \ + max_val = scan->value; \ +\ + first = false; \ + } \ + else if (_map_->f_key->cmp(scan->key, max_key) > 0) \ + { \ + max_key = scan->key; \ + max_val = scan->value; \ + } \ +\ + scan = scan->next; \ } \ } \ \ @@ -728,27 +731,30 @@ return false; \ } \ \ - K min_key = (K) { 0 }; \ - V min_val = (V) { 0 }; \ + bool first = true; \ + K min_key = (K){ 0 }; \ + V min_val = (V){ 0 }; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ -\ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ - K result_key = CMC_(PFX, _iter_key)(&iter); \ - V result_value = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ \ - if (index == 0) \ + while (scan) \ { \ - 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 (first) \ + { \ + min_key = scan->key; \ + min_val = scan->value; \ +\ + first = false; \ + } \ + else if (_map_->f_key->cmp(scan->key, min_key) < 0) \ + { \ + min_key = scan->key; \ + min_val = scan->value; \ + } \ +\ + scan = scan->next; \ } \ } \ \ @@ -893,16 +899,17 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ -\ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - V value = CMC_(PFX, _iter_value)(&iter); \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ \ - /* TODO check for errors */ \ - CMC_(PFX, _insert)(_new_map_, key, value); \ + while (scan) \ + { \ + /* TODO check for errors */ \ + CMC_(PFX, _insert)(_new_map_, scan->key, scan->value); \ +\ + scan = scan->next; \ + } \ } \ \ if (_map_->count != _new_map_->count) \ @@ -946,23 +953,28 @@ return NULL; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ -\ - if (!CMC_(PFX, _empty)(_map_)) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ +\ + while (scan) \ { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - V value = CMC_(PFX, _iter_value)(&iter); \ + K key;\ + V value;\ \ if (_map_->f_key->cpy) \ - key = _map_->f_key->cpy(key); \ + key = _map_->f_key->cpy(scan->key); \ + else\ + key = scan->key;\ if (_map_->f_val->cpy) \ - value = _map_->f_val->cpy(value); \ + value = _map_->f_val->cpy(scan->value); \ + else\ + value = scan->value;\ \ /* TODO check for errors */ \ CMC_(PFX, _insert)(result, key, value); \ +\ + scan = scan->next; \ } \ } \ \ @@ -980,15 +992,25 @@ if (_map1_->count != _map2_->count) \ return false; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ + /* Optimize loop using the smallest hashtable */ \ + struct SNAME *_map_a_; \ + struct SNAME *_map_b_; \ \ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \ + _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \ +\ + for (size_t i = 0; i < _map_a_->capacity; i++) \ { \ - K key = CMC_(PFX, _iter_key)(&iter); \ + struct CMC_DEF_ENTRY(SNAME) *scan = _map_a_->buffer[i][0]; \ \ - if (CMC_(PFX, _impl_key_count)(_map1_, key) != CMC_(PFX, _impl_key_count)(_map2_, key)) \ - return false; \ + while (scan) \ + { \ + /* OPTIMIZE - This is calling key_count for repeating keys */\ + if (CMC_(PFX, _impl_key_count)(_map_a_, scan->key) != CMC_(PFX, _impl_key_count)(_map_b_, scan->key))\ + return false;\ +\ + scan = scan->next; \ + } \ } \ \ return true; \ @@ -1015,7 +1037,7 @@ \ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \ \ - while (entry != NULL) \ + while (entry) \ { \ if (_map_->f_key->cmp(entry->key, key) == 0) \ return entry; \ @@ -1037,7 +1059,7 @@ if (!entry) \ return total_count; \ \ - while (entry != NULL) \ + while (entry) \ { \ if (_map_->f_key->cmp(entry->key, key) == 0) \ total_count++; \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index be14e5f..eaa3f08 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -477,7 +477,7 @@ return false; \ } \ \ - V max_val = (V) { 0 }; \ + V max_val = (V){ 0 }; \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO transform this into a normal loop */ \ @@ -510,7 +510,7 @@ return false; \ } \ \ - V min_val = (V) { 0 }; \ + V min_val = (V){ 0 }; \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO transform this into a normal loop */ \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 47bdf4f..35b2fa9 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -378,7 +378,7 @@ return false; \ } \ \ - V max_val = (V) { 0 }; \ + V max_val = (V){ 0 }; \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO turn this into a normal loop */ \ @@ -411,7 +411,7 @@ return false; \ } \ \ - V min_val = (V) { 0 }; \ + V min_val = (V){ 0 }; \ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ /* TODO turn this into a normal loop */ \ diff --git a/src/ext/cmc/treeset.h b/src/ext/cmc/treeset.h index 674fef4..9cc5ce5 100644 --- a/src/ext/cmc/treeset.h +++ b/src/ext/cmc/treeset.h @@ -557,7 +557,6 @@ return true; \ } - /** * STR */ diff --git a/tests/src/cmc/hashmultimap.c b/tests/src/cmc/hashmultimap.c index 41d0817..f99130c 100644 --- a/tests/src/cmc/hashmultimap.c +++ b/tests/src/cmc/hashmultimap.c @@ -48,7 +48,7 @@ void hmm_clear(struct hashmultimap *_map_) for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan != ((void *)0)) + while (scan) { struct hashmultimap_entry *next = scan->next; if (_map_->f_key->free) @@ -69,7 +69,7 @@ void hmm_free(struct hashmultimap *_map_) while (index < _map_->capacity) { struct hashmultimap_entry *scan = _map_->buffer[index][0]; - if (scan != ((void *)0)) + if (scan) { if (scan->next == ((void *)0) && scan->prev == ((void *)0)) { @@ -81,7 +81,7 @@ void hmm_free(struct hashmultimap *_map_) } else { - while (scan != ((void *)0)) + while (scan) { struct hashmultimap_entry *tmp = scan; scan = scan->next; @@ -188,7 +188,7 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, } } size_t index = 0; - while (entry != ((void *)0)) + while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) { @@ -239,7 +239,7 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) else { _Bool found = 0; - while (entry != ((void *)0)) + while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) { @@ -247,9 +247,9 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) *head = entry->next; if (*tail == entry) *tail = entry->prev; - if (entry->prev != ((void *)0)) + if (entry->prev) entry->prev->next = entry->next; - if (entry->next != ((void *)0)) + if (entry->next) entry->next->prev = entry->prev; if (out_value) *out_value = entry->value; @@ -316,7 +316,7 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_value } else { - while (entry != ((void *)0)) + while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) { @@ -325,9 +325,9 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_value if (*tail == entry) *tail = entry->prev; struct hashmultimap_entry *next = entry->next; - if (entry->prev != ((void *)0)) + if (entry->prev) entry->prev->next = entry->next; - if (entry->next != ((void *)0)) + if (entry->next) entry->next->prev = entry->prev; if (out_values) (*out_values)[index] = entry->value; @@ -353,23 +353,26 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; - struct hashmultimap_iter iter = hmm_iter_start(_map_); - for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter)) + for (size_t i = 0; i < _map_->capacity; i++) { - size_t result_key = hmm_iter_key(&iter); - size_t result_value = hmm_iter_value(&iter); - size_t index = hmm_iter_index(&iter); - if (index == 0) + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) { - 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 (first) + { + max_key = scan->key; + max_val = scan->value; + first = 0; + } + else if (_map_->f_key->cmp(scan->key, max_key) > 0) + { + max_key = scan->key; + max_val = scan->value; + } + scan = scan->next; } } if (key) @@ -389,23 +392,26 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t min_key = (size_t){ 0 }; size_t min_val = (size_t){ 0 }; - struct hashmultimap_iter iter = hmm_iter_start(_map_); - for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter)) + for (size_t i = 0; i < _map_->capacity; i++) { - size_t result_key = hmm_iter_key(&iter); - size_t result_value = hmm_iter_value(&iter); - size_t index = hmm_iter_index(&iter); - if (index == 0) + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) { - 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 (first) + { + min_key = scan->key; + min_val = scan->value; + first = 0; + } + else if (_map_->f_key->cmp(scan->key, min_key) < 0) + { + min_key = scan->key; + min_val = scan->value; + } + scan = scan->next; } } if (key) @@ -518,12 +524,14 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) _map_->flag = CMC_FLAG_ALLOC; return 0; } - struct hashmultimap_iter iter = hmm_iter_start(_map_); - for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter)) + for (size_t i = 0; i < _map_->capacity; i++) { - size_t key = hmm_iter_key(&iter); - size_t value = hmm_iter_value(&iter); - hmm_insert(_new_map_, key, value); + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) + { + hmm_insert(_new_map_, scan->key, scan->value); + scan = scan->next; + } } if (_map_->count != _new_map_->count) { @@ -555,18 +563,23 @@ struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } - struct hashmultimap_iter iter = hmm_iter_start(_map_); - if (!hmm_empty(_map_)) + for (size_t i = 0; i < _map_->capacity; i++) { - for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter)) + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) { - size_t key = hmm_iter_key(&iter); - size_t value = hmm_iter_value(&iter); + size_t key; + size_t value; if (_map_->f_key->cpy) - key = _map_->f_key->cpy(key); + key = _map_->f_key->cpy(scan->key); + else + key = scan->key; if (_map_->f_val->cpy) - value = _map_->f_val->cpy(value); + value = _map_->f_val->cpy(scan->value); + else + value = scan->value; hmm_insert(result, key, value); + scan = scan->next; } } (result)->callbacks = _map_->callbacks; @@ -579,12 +592,19 @@ _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_) _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; - struct hashmultimap_iter iter = hmm_iter_start(_map1_); - for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter)) + struct hashmultimap *_map_a_; + struct hashmultimap *_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++) { - size_t key = hmm_iter_key(&iter); - if (hmm_impl_key_count(_map1_, key) != hmm_impl_key_count(_map2_, key)) - return 0; + struct hashmultimap_entry *scan = _map_a_->buffer[i][0]; + while (scan) + { + if (hmm_impl_key_count(_map_a_, scan->key) != hmm_impl_key_count(_map_b_, scan->key)) + return 0; + scan = scan->next; + } } return 1; } @@ -603,7 +623,7 @@ struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t { size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - while (entry != ((void *)0)) + while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) return entry; @@ -618,7 +638,7 @@ size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) size_t total_count = 0; if (!entry) return total_count; - while (entry != ((void *)0)) + while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) total_count++; diff --git a/tests/unt/cmc/hashmultimap.h b/tests/unt/cmc/hashmultimap.h index 343ff93..c901a48 100644 --- a/tests/unt/cmc/hashmultimap.h +++ b/tests/unt/cmc/hashmultimap.h @@ -227,6 +227,103 @@ CMC_CREATE_UNIT(CMCHashMultiMap, true, { hmm_free(map); }); + CMC_CREATE_TEST(PFX##_max(), { + struct hashmultimap *map = hmm_new(50, 0.8, hmm_fkey, hmm_fval); + + size_t max_key; + size_t max_val; + cmc_assert(!hmm_max(map, &max_key, &max_val)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, map->flag); + + cmc_assert(hmm_insert(map, 1, 2)); + cmc_assert(hmm_max(map, &max_key, &max_val)); + cmc_assert_equals(size_t, 1, max_key); + cmc_assert_equals(size_t, 2, max_val); + + cmc_assert(hmm_insert(map, 2, 3)); + cmc_assert(hmm_insert(map, 0, 1)); + cmc_assert(hmm_max(map, &max_key, &max_val)); + cmc_assert_equals(size_t, 2, max_key); + cmc_assert_equals(size_t, 3, max_val); + + for (size_t i = 3; i <= 100; i++) + { + cmc_assert(hmm_insert(map, i, i)); + } + + cmc_assert(hmm_max(map, &max_key, &max_val)); + cmc_assert_equals(size_t, 100, max_key); + cmc_assert_equals(size_t, 100, max_val); + + hmm_free(map); + }); + + CMC_CREATE_TEST(PFX##_min(), { + struct hashmultimap *map = hmm_new(50, 0.8, hmm_fkey, hmm_fval); + + size_t min_key; + size_t min_val; + cmc_assert(!hmm_min(map, &min_key, &min_val)); + cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, map->flag); + + cmc_assert(hmm_insert(map, 1, 2)); + cmc_assert(hmm_min(map, &min_key, &min_val)); + cmc_assert_equals(size_t, 1, min_key); + cmc_assert_equals(size_t, 2, min_val); + + cmc_assert(hmm_insert(map, 2, 3)); + cmc_assert(hmm_insert(map, 0, 1)); + cmc_assert(hmm_min(map, &min_key, &min_val)); + cmc_assert_equals(size_t, 0, min_key); + cmc_assert_equals(size_t, 1, min_val); + + for (size_t i = 3; i <= 100; i++) + { + cmc_assert(hmm_insert(map, i, i)); + } + + cmc_assert(hmm_min(map, &min_key, &min_val)); + cmc_assert_equals(size_t, 0, min_key); + cmc_assert_equals(size_t, 1, min_val); + + hmm_free(map); + }); + + CMC_CREATE_TEST(PFX##_copy_of(), { + struct hashmultimap *map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); + + for (size_t i = 0; i < 1000; i++) + hmm_insert(map, i, i); + + struct hashmultimap *map2 = hmm_copy_of(map); + + cmc_assert_equals(size_t, map->count, map2->count); + cmc_assert(hmm_equals(map, map2)); + + hmm_free(map); + }); + + CMC_CREATE_TEST(PFX##_equals(), { + struct hashmultimap *map1 = hmm_new(100, 0.8, hmm_fkey, hmm_fval); + struct hashmultimap *map2 = hmm_new(100, 0.8, hmm_fkey, hmm_fval); + + cmc_assert(hmm_equals(map1, map2)); + + cmc_assert(hmm_insert(map1, 1, 1)); + cmc_assert(hmm_insert(map2, 1, 1)); + cmc_assert(hmm_equals(map1, map2)); + + for (size_t i = 2; i < 200; i++) + { + cmc_assert(hmm_insert(map1, i, i) && hmm_insert(map2, i, i)); + } + + cmc_assert(hmm_equals(map1, map2)); + + hmm_free(map1); + hmm_free(map2); + }); + CMC_CREATE_TEST(key_count, { struct hashmultimap *map = hmm_new(50, 0.8, hmm_fkey, hmm_fval); From cf9c684ecb30b35a17da74d6d54d41dc7219240e Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 29 Jun 2020 17:50:30 -0300 Subject: [PATCH 02/20] hashbidimap fixes --- src/cmc/hashbidimap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h index 9edab75..9680303 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc/hashbidimap.h @@ -515,7 +515,7 @@ } \ \ /* The mapping key -> new_val is already true */ \ - if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) \ + if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) \ goto success; \ \ if (CMC_(PFX, _impl_get_entry_by_val)(_map_, new_val) != NULL) \ @@ -657,7 +657,7 @@ if (!entry) \ { \ _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ + return (K){ 0 }; \ } \ \ _map_->flag = CMC_FLAG_OK; \ From 27d70cb32c4ee5560f065d66774cc10e9e993ca3 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 30 Jun 2020 23:29:52 -0300 Subject: [PATCH 03/20] Trying to fix code coverage --- autogen.py | 280 +++++++++++++++++++++++++++++------------------- tests/codecov.c | 140 ++++++++++++++++++++++++ 2 files changed, 310 insertions(+), 110 deletions(-) create mode 100644 tests/codecov.c diff --git a/autogen.py b/autogen.py index bb4bec0..5275234 100644 --- a/autogen.py +++ b/autogen.py @@ -1,5 +1,4 @@ -# A script that automatically generates code for code coverage, updates tests -# and Makefiles, and creates necessary directories +# A script for automation import argparse import os @@ -12,11 +11,9 @@ from typing import List, Text # Config Script Configuration # Directories Names for directories -# Output Where the outputted code is to be put -# Build Where the build objects are to be located +# Files Names for files # Compiler Compiler Configurations -# Compilation Tests, code coverage and flags -# Macro Expansion Configuration for the code expansion +# Macro Expansion Configuration for the code expansion # Collections All collections # # Variables marked as const are to not be modified @@ -25,7 +22,7 @@ from typing import List, Text # Output directory # In this directory it is assumed that the following files and directories are -# included: main.c, unt folder +# included: main.c, codecov.c, unt folder OUTPUT_DIR = './tests' # All libraries ALL_LIBS = ['CMC'] @@ -39,33 +36,46 @@ BUILD_DIR = f'{OUTPUT_DIR}/build' INCLUDE_DIR = f"{OUTPUT_DIR}/{DIR_MAP['HEADER']}" # const SRC_DIR = f"{OUTPUT_DIR}/{DIR_MAP['SOURCE']}" +# Where executables go +BIN_DIR = f'{BUILD_DIR}/bin' # Where object files .o go OBJ_DIR = BUILD_DIR -# The name of the main test executable -TEST_EXE = f'{OUTPUT_DIR}/main.exe' # Where .gcov files should go GCOV_DIR = f'{BUILD_DIR}/gcov' +# Files +# All const + +# The name of the main test +MAIN = 'main' +# The name of the code coverage file +CODECOV = 'codecov' +# The name of the single test file +SINGLE = 'single' + # Compiler -# Compilation +# Compiler to be used CC = 'gcc' # Compilation Flags -CFLAGS = ['-Wall', '-Werror'] +CFLAGS = ['-Wall', '-Werror', '-O3'] # Link flags LFLAGS = [] # Coverage Flags CVFLAGS = ['--coverage', '-O0'] # gcov flags GCOV_FLAGS = [] -# Include to the main Library +# Include of the main library # const INCLUDE = ['-I', './src'] # Include to the test file headers # const TINCLUDE = ['-I', f'{INCLUDE_DIR}'] +# Include to code coverage +# const +CVINCLUDE = ['-I', INCLUDE_DIR, '-I', SRC_DIR] -# Macro expansion +# Macro Expansion # -E Only preprocessor # -P No linemarkers @@ -78,30 +88,6 @@ UNIQUE_FLAG = '// C_MACRO_COLLECTIONS_CODE' # Temporary file used to expand the macros TMP_FILE = './main.c' -# Just a realy helpfull overview -CONFIG = f'''Directory Settings - OUTPUT_DIR = {OUTPUT_DIR} - ALL_LIBS = {ALL_LIBS} - DIR_MAP = {DIR_MAP} - EXT_MAP = {EXT_MAP} - BUILD_DIR = {BUILD_DIR} - INCLUDE_DIR = {INCLUDE_DIR} - SRC_DIR = {SRC_DIR} - OBJ_DIR = {OBJ_DIR} - GCOV_DIR = {GCOV_DIR} -Compiler Settings - CC = {CC} - CFLAGS = {CFLAGS} - LFLAGS = {LFLAGS} - CVFLAGS = {CVFLAGS} - GCOV_FLAGS = {GCOV_FLAGS} - INCLUDE = {INCLUDE} - TINCLUDE = {TINCLUDE} -Macro Expansion - EXPAND_FLAGS = {EXPAND_FLAGS} - UNIQUE_FLAG = {UNIQUE_FLAG} - TMP_FILE = {TMP_FILE}''' - # All collections that can be used for testing COLLECTIONS = [ @@ -125,6 +111,36 @@ COLLECTIONS = [ ] +# Just a realy helpfull overview +CONFIG = f'''Directory Settings + OUTPUT_DIR = {OUTPUT_DIR} + ALL_LIBS = {ALL_LIBS} + DIR_MAP = {DIR_MAP} + EXT_MAP = {EXT_MAP} + BUILD_DIR = {BUILD_DIR} + INCLUDE_DIR = {INCLUDE_DIR} + SRC_DIR = {SRC_DIR} + OBJ_DIR = {OBJ_DIR} + GCOV_DIR = {GCOV_DIR} +File Settings + MAIN = {MAIN} + CODECOV = {CODECOV} + SINGLE = {SINGLE} +Compiler Settings + CC = {CC} + CFLAGS = {CFLAGS} + LFLAGS = {LFLAGS} + CVFLAGS = {CVFLAGS} + GCOV_FLAGS = {GCOV_FLAGS} + INCLUDE = {INCLUDE} + TINCLUDE = {TINCLUDE} + CVINCLUDE = {CVINCLUDE} +Macro Expansion + EXPAND_FLAGS = {EXPAND_FLAGS} + UNIQUE_FLAG = {UNIQUE_FLAG} + TMP_FILE = {TMP_FILE}''' + + def full_path(path: Text) -> Text: ''' Returns the full path of a 'path' with ralative paths, e.g. './' or '../' @@ -142,18 +158,28 @@ def execute_command(commands: List[Text]): # exit(1) -def assert_executable(program: Text): +def require_executable(program: Text): ''' - Asserts that a given program is installed and available in PATH. + Asserts that a given program is installed and available in PATH. Raises an exception if it doesn't. ''' if shutil.which(program) is None: raise Exception(f'The required executable {program} was not found in your path') +def require_file(file: Text): + ''' + Asserts that a given file exists. Raises an exception if it doesn't. + ''' + f = pathlib.Path(file).resolve() + if not f.is_file(): + raise Exception(f'The required file {str(f)} was not found') + + def assert_dir(directory: Text): ''' Given a string 'directory' that is a path to a directory, make sure that it exists. ''' + # TODO change this to use pathlib ? if not os.path.exists(directory): os.makedirs(directory) @@ -175,19 +201,30 @@ def assert_structure(): assert_dir(BUILD_DIR) assert_dir(OBJ_DIR) + assert_dir(BIN_DIR) assert_dir(GCOV_DIR) for lib in ALL_LIBS: assert_dir(f'{OBJ_DIR}/{lib.lower()}') +def format_code(source: bool, tests: bool): + ''' + Format all source files from the main library or test files. + ''' + if source: + execute_command(['find', './src/', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) + if tests: + execute_command(['find', './tests/', '-name', '*.c', '-o', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) + + def clean_build(cleanfull: bool): ''' Removes all files generated by compilation and code coverage along with folders. ''' # -f prevents 'rm' from failing execute_command(['rm', '-r', '-f', f'{GCOV_DIR}/*.gcov']) - execute_command(['rm', '-f', TEST_EXE]) + execute_command(['rm', '-r', '-f', f'{OUTPUT_DIR}/*.exe']) execute_command(['rm', '-r', '-f', BUILD_DIR]) if cleanfull: @@ -267,30 +304,12 @@ def format_expand(): execute_command(cmd) -def format_code(source: bool, tests: bool): +def build_main(): ''' - Format all source files from the main library or test files. + Build all object files and main.c for tests. ''' - if source: - execute_command(['find', './src/', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) - if tests: - execute_command(['find', './tests/', '-name', '*.c', '-o', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) - - -def build_tests(with_coverage: bool): - ''' - Build all object files and the main executable for tests - ''' - cflags = CFLAGS.copy() - - if with_coverage: - cflags += CVFLAGS - else: - cflags += ['-O3'] - for data in COLLECTIONS: cmd = [CC] - cmd += cflags cmd += TINCLUDE # This one needs to go first cmd += INCLUDE cmd += ['-c', f"{SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c"] @@ -299,34 +318,48 @@ def build_tests(with_coverage: bool): # Build OUTPUT_DIR/main.c cmd = [CC] - cmd += cflags cmd += TINCLUDE # This one needs to go first cmd += INCLUDE - cmd += ['-c', f'{OUTPUT_DIR}/main.c'] - cmd += ['-o', f"{OBJ_DIR}/main.o"] + cmd += ['-c', f'{OUTPUT_DIR}/{MAIN}.c'] + cmd += ['-o', f'{OBJ_DIR}/{MAIN}.o'] execute_command(cmd) # Link everything producing OUTPUT_DIR/main.exe cmd = [CC] - cmd += cflags cmd += LFLAGS - cmd += ['-o', TEST_EXE] + cmd += ['-o', f'{BIN_DIR}/{MAIN}.exe'] cmd += [f'{OBJ_DIR}/main.o'] cmd += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS] execute_command(cmd) -def run_tests(coverage: bool): +def run_main(): ''' - Runs tests. If coverage, run gcov. + Runs main.exe ''' - execute_command([full_path(TEST_EXE)]) + execute_command([full_path(f'{BIN_DIR}/{MAIN}.exe')]) - if coverage: - objects = [f'{OBJ_DIR}/main.gcda'] - objects += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.gcda' for data in COLLECTIONS] - execute_command(['gcov'] + GCOV_FLAGS + objects) - execute_command(['mv', '*.gcov', GCOV_DIR]) + +def build_codecov(): + ''' + Builds codecov.c for code coverage. + ''' + cmd = [CC] + cmd += CVFLAGS + cmd += CVINCLUDE # This one needs to go first + cmd += INCLUDE + cmd += [f'{OUTPUT_DIR}/{CODECOV}.c'] + cmd += ['-o', f'{BIN_DIR}/{CODECOV}.exe'] + execute_command(cmd) + + +def run_codecov(): + ''' + Runs codecov.exe and then gcov on the generated gcda files. All gcov files then go to GCOV_DIR. + ''' + execute_command([full_path(f'{BIN_DIR}/{CODECOV}.exe')]) + execute_command(['gcov'] + GCOV_FLAGS + [f'{CODECOV}.gcda']) + execute_command(['mv', '*.gcov', GCOV_DIR]) if __name__ == '__main__': @@ -334,53 +367,64 @@ if __name__ == '__main__': p.add_argument('-sc', '--show-config', help='Displays the current configuration', + default=False, action='store_true', dest='config') - tests = p.add_argument_group('tests', 'For dealing with tests') + source = p.add_argument_group('source', 'For dealing with the source files and formatting') - tests.add_argument('-c', '--clean', + expand = p.add_argument_group('expand', 'For dealing with code generation and formatting for tests') + + task = p.add_argument_group('task', 'Specify a task (mutually exclusive)') + task_ = task.add_mutually_exclusive_group(required=True) + + action = p.add_argument_group('action', 'Actions on task') + + task_.add_argument('-cv', '--codecov', + help='Designates task as code coverage (uses codecov.c)', + default=False, + action='store_true', + dest='codecov') + task_.add_argument('-m', '--main', + help='Designates task as the main tests (uses main.c)', + default=False, + action='store_true', + dest='main') + task_.add_argument('-s', '--single', + help='Designates task as an individual test (uses single.c)', + dest='single') + + expand.add_argument('-c', '--clean', help='Cleans all build objects', default=False, action='store_true', dest='clean') - tests.add_argument('-cf', '--clean-full', + expand.add_argument('-cf', '--clean-full', help='Cleans all build objects, source and header files, and removes folders', default=False, action='store_true', dest='cleanfull') - tests.add_argument('-e', '--expand', + expand.add_argument('-e', '--expand', help='Expands the header and source files', default=False, action='store_true', dest='expand') - tests.add_argument('-nf', '--no-format', + expand.add_argument('-nf', '--no-format', help='Does not format the output of expand. Can be used when you might not have clang-format', default=False, action='store_true', dest='noformat') - tests.add_argument('-b', '--build', - help='Compile the object files and the main executable', + + action.add_argument('-b', '--build', + help='Build task', default=False, action='store_true', dest='build') - tests.add_argument('-r', '--run', - help='Runs tests, assuming that it is already built', + action.add_argument('-r', '--run', + help='Run task', default=False, action='store_true', dest='run') - tests.add_argument('-cv', '--coverage', - help='Adds the code coverage flags for compilation', - default=False, - action='store_true', - dest='coverage') - tests.add_argument('-rr', '--rerun', - help='Compile the object files again and then run the tests', - default=False, - action='store_true', - dest='rerun') - - source = p.add_argument_group('source', 'For dealing with the source files and formatting') source.add_argument('-fs', '--format-source', help='Format the source code', @@ -399,34 +443,50 @@ if __name__ == '__main__': print(CONFIG) exit(0) - if args.clean or args.cleanfull: - clean_build(args.cleanfull) + if args.fmt_source or args.fmt_tests: + require_executable('find') + require_executable('xargs') + format_code(args.fmt_source, args.fmt_tests) + # Prevent mixing code + exit(0) if not args.cleanfull: assert_structure() - assert_executable(CC) + if args.clean: + clean_build(False) + else: + clean_build(True) + # Nothing else will work, so just exit + exit(0) if args.expand: expand_code() if not args.noformat: - assert_executable('clang-format') + require_executable('clang-format') format_expand() else: # In case the next task is to build the code from source # This warning is a very annoying one from gcc CFLAGS += ['-Wno-misleading-indentation'] - if args.fmt_source or args.fmt_tests: - assert_executable('find') - assert_executable('xargs') - format_code(args.fmt_source, args.fmt_tests) - if args.build: - build_tests(args.coverage) + require_executable(CC) + if args.codecov: + require_executable('gcov') + + if args.codecov: + require_file(f'{OUTPUT_DIR}/{CODECOV}.c') + require_executable + if args.build: + build_codecov() if args.run: - run_tests(args.coverage) - elif args.rerun: - build_tests(args.coverage) - run_tests(args.coverage) - elif args.run: - run_tests(args.coverage) + run_codecov() + elif args.main: + require_file(f'{OUTPUT_DIR}/{MAIN}.c') + if args.build: + build_main() + if args.run: + run_main() + elif args.single: + require_file(f'{OUTPUT_DIR}/{SINGLE}.c') + # TODO diff --git a/tests/codecov.c b/tests/codecov.c new file mode 100644 index 0000000..442ba00 --- /dev/null +++ b/tests/codecov.c @@ -0,0 +1,140 @@ +// Specifically used for code coverage + +#include +#include + +#include "macro_collections.h" + +#include "cmc/bitset.h" +#include "cmc/deque.h" +#include "cmc/hashbidimap.h" +#include "cmc/hashmap.h" +#include "cmc/hashmultimap.h" +#include "cmc/hashmultiset.h" +#include "cmc/hashset.h" +#include "cmc/heap.h" +#include "cmc/intervalheap.h" +#include "cmc/linkedlist.h" +#include "cmc/list.h" +#include "cmc/queue.h" +#include "cmc/sortedlist.h" +#include "cmc/stack.h" +#include "cmc/treemap.h" +#include "cmc/treeset.h" + +#include "cmc/bitset.c" +#include "cmc/deque.c" +#include "cmc/hashbidimap.c" +#include "cmc/hashmap.c" +#include "cmc/hashmultimap.c" +#include "cmc/hashmultiset.c" +#include "cmc/hashset.c" +#include "cmc/heap.c" +#include "cmc/intervalheap.c" +#include "cmc/linkedlist.c" +#include "cmc/list.c" +#include "cmc/queue.c" +#include "cmc/sortedlist.c" +#include "cmc/stack.c" +#include "cmc/treemap.c" +#include "cmc/treeset.c" + +#include "unt/cmc/bitset.h" +#include "unt/cmc/deque.h" +#include "unt/cmc/hashbidimap.h" +#include "unt/cmc/hashmap.h" +#include "unt/cmc/hashmultimap.h" +#include "unt/cmc/hashmultiset.h" +#include "unt/cmc/hashset.h" +#include "unt/cmc/heap.h" +#include "unt/cmc/intervalheap.h" +#include "unt/cmc/linkedlist.h" +#include "unt/cmc/list.h" +#include "unt/cmc/queue.h" +#include "unt/cmc/sortedlist.h" +#include "unt/cmc/stack.h" +#include "unt/cmc/treemap.h" +#include "unt/cmc/treeset.h" + +#include "unt/utl/foreach.h" + +#include "utl/assert.h" +#include "utl/timer.h" + +#include "./unt/utl.h" + +#define cmc_run(unit, unit_fails, test_fails) \ + do \ + { \ + uintmax_t f = unit(); \ + if (f != 0) \ + unit_fails += 1; \ + test_fails += f; \ + } while (0) + +int main(void) +{ + // clang-format off + printf(" +---------------------------------------------------------------+\n"); + printf(" | C Macro Collections Library |\n"); + printf(" | |\n"); + printf(" | Code Coverage Suite |\n"); + printf(" | |\n"); + printf(" | https://github.com/LeoVen/C-Macro-Collections |\n"); + printf(" | Leonardo Vencovsky (leonardo.vencovsky@gmail.com) |\n"); + printf(" +---------------------------------------------------------------+\n\n"); + // clang-format on + + struct cmc_timer timer; + + cmc_timer_start(timer); + uintmax_t tests = 0, units = 0; + + cmc_run(CMCBitSet, units, tests); + cmc_run(CMCBitSetIter, units, tests); + cmc_run(CMCDeque, units, tests); + cmc_run(CMCDequeIter, units, tests); + cmc_run(CMCHashBidiMap, units, tests); + cmc_run(CMCHashBidiMapIter, units, tests); + cmc_run(CMCHashMap, units, tests); + cmc_run(CMCHashMapIter, units, tests); + cmc_run(CMCHashMultiMap, units, tests); + cmc_run(CMCHashMultiMapIter, units, tests); + cmc_run(CMCHashMultiSet, units, tests); + cmc_run(CMCHashMultiSetIter, units, tests); + cmc_run(CMCHashSet, units, tests); + cmc_run(CMCHashSetIter, units, tests); + cmc_run(CMCHeap, units, tests); + cmc_run(CMCHeapIter, units, tests); + cmc_run(CMCIntervalHeap, units, tests); + cmc_run(CMCIntervalHeapIter, units, tests); + cmc_run(CMCLinkedList, units, tests); + cmc_run(CMCLinkedListIter, units, tests); + cmc_run(CMCList, units, tests); + cmc_run(CMCListIter, units, tests); + cmc_run(CMCQueue, units, tests); + cmc_run(CMCQueueIter, units, tests); + cmc_run(CMCSortedList, units, tests); + cmc_run(CMCSortedListIter, units, tests); + cmc_run(CMCStack, units, tests); + cmc_run(CMCStackIter, units, tests); + cmc_run(CMCTreeMap, units, tests); + cmc_run(CMCTreeMapIter, units, tests); + cmc_run(CMCTreeSet, units, tests); + cmc_run(CMCTreeSetIter, units, tests); + + cmc_run(ForEach, units, tests); + + cmc_timer_stop(timer); + + printf(" +---------------------------------------------------------------+\n"); + printf(" | SUMMARY |\n"); + printf(" +---------------------------------------------------------------+\n"); + printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units); + printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests); + printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", cmc_assert_failed); + printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result); + printf(" +---------------------------------------------------------------+\n"); + + return tests; +} From 3f97fca40efca8a0e3e9291deed60ca366b0d79e Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 30 Jun 2020 23:57:58 -0300 Subject: [PATCH 04/20] Update autogen.py --- .travis.yml | 2 +- autogen.py | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index eb93d61..b001f94 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,6 @@ script: - gcc --version - gcov --version - python --version - - python autogen.py -e -b -cv -r -nf + - python autogen.py -e -b -cv -r -nf -nt after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/autogen.py b/autogen.py index 5275234..2797375 100644 --- a/autogen.py +++ b/autogen.py @@ -359,6 +359,13 @@ def run_codecov(): ''' execute_command([full_path(f'{BIN_DIR}/{CODECOV}.exe')]) execute_command(['gcov'] + GCOV_FLAGS + [f'{CODECOV}.gcda']) + execute_command(['rm', '*.h.gcov']) + + +def tidy(): + ''' + Places files to their respective directory. + ''' execute_command(['mv', '*.gcov', GCOV_DIR]) @@ -376,7 +383,7 @@ if __name__ == '__main__': expand = p.add_argument_group('expand', 'For dealing with code generation and formatting for tests') task = p.add_argument_group('task', 'Specify a task (mutually exclusive)') - task_ = task.add_mutually_exclusive_group(required=True) + task_ = task.add_mutually_exclusive_group() action = p.add_argument_group('action', 'Actions on task') @@ -414,6 +421,11 @@ if __name__ == '__main__': default=False, action='store_true', dest='noformat') + expand.add_argument('-nt', '--no-tidy', + help='Don\'t move files around', + default=False, + action='store_true', + dest='notidy') action.add_argument('-b', '--build', help='Build task', @@ -439,6 +451,8 @@ if __name__ == '__main__': args = p.parse_args() + has_target = args.main or args.codecov or args.single + if args.config: print(CONFIG) exit(0) @@ -490,3 +504,6 @@ if __name__ == '__main__': elif args.single: require_file(f'{OUTPUT_DIR}/{SINGLE}.c') # TODO + + if not args.notidy and has_target: + tidy() From 18a8810c4c9d9f6921b8b9e96bdbf6f1f23526fb Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 1 Jul 2020 23:46:36 -0300 Subject: [PATCH 05/20] Formatting, HashMultiSet no longer depends on ITER --- autogen.py | 2 +- src/cmc/hashmap.h | 45 +++++++---------- src/cmc/hashmultimap.h | 18 +++---- src/cmc/hashmultiset.h | 95 +++++++++++++++++++++++------------- tests/src/cmc/hashbidimap.c | 2 +- tests/src/cmc/hashmap.c | 42 +++++++--------- tests/src/cmc/hashmultiset.c | 82 ++++++++++++++++++++----------- 7 files changed, 161 insertions(+), 125 deletions(-) diff --git a/autogen.py b/autogen.py index 2797375..c160e31 100644 --- a/autogen.py +++ b/autogen.py @@ -505,5 +505,5 @@ if __name__ == '__main__': require_file(f'{OUTPUT_DIR}/{SINGLE}.c') # TODO - if not args.notidy and has_target: + if not args.notidy and args.codecov: tidy() diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 587370b..747d516 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -461,25 +461,21 @@ return false; \ } \ \ + bool first = true; \ K max_key = (K){ 0 }; \ V max_val = (V){ 0 }; \ - 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++) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ if (_map_->buffer[i].state == CMC_ES_FILLED) \ { \ - if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ + if (first) \ + { \ + max_key = _map_->buffer[i].key; \ + max_val = _map_->buffer[i].value; \ + first = false; \ + } \ + else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ { \ max_key = _map_->buffer[i].key; \ max_val = _map_->buffer[i].value; \ @@ -505,25 +501,21 @@ return false; \ } \ \ + bool first = true; \ K min_key = (K){ 0 }; \ V min_val = (V){ 0 }; \ - 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++) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ if (_map_->buffer[i].state == CMC_ES_FILLED) \ { \ - if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \ + if (first) \ + { \ + min_key = _map_->buffer[i].key; \ + min_val = _map_->buffer[i].value; \ + first = false; \ + } \ + else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \ { \ min_key = _map_->buffer[i].key; \ min_val = _map_->buffer[i].value; \ @@ -780,7 +772,6 @@ 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) \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index b1dbd55..8371e5a 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -959,17 +959,17 @@ \ while (scan) \ { \ - K key;\ - V value;\ + K key; \ + V value; \ \ if (_map_->f_key->cpy) \ key = _map_->f_key->cpy(scan->key); \ - else\ - key = scan->key;\ + else \ + key = scan->key; \ if (_map_->f_val->cpy) \ value = _map_->f_val->cpy(scan->value); \ - else\ - value = scan->value;\ + else \ + value = scan->value; \ \ /* TODO check for errors */ \ CMC_(PFX, _insert)(result, key, value); \ @@ -1005,9 +1005,9 @@ \ while (scan) \ { \ - /* OPTIMIZE - This is calling key_count for repeating keys */\ - if (CMC_(PFX, _impl_key_count)(_map_a_, scan->key) != CMC_(PFX, _impl_key_count)(_map_b_, scan->key))\ - return false;\ + /* OPTIMIZE - This is calling key_count for repeating keys */ \ + if (CMC_(PFX, _impl_key_count)(_map_a_, scan->key) != CMC_(PFX, _impl_key_count)(_map_b_, scan->key)) \ + return false; \ \ scan = scan->next; \ } \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index eaa3f08..8cfff7d 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -477,19 +477,23 @@ return false; \ } \ \ + bool first = true; \ V max_val = (V){ 0 }; \ - 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)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - 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 (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (first) \ + { \ + max_val = _set_->buffer[i].value; \ + first = false; \ + } \ + else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) \ + { \ + max_val = _set_->buffer[i].value; \ + } \ + } \ } \ \ if (value) \ @@ -510,19 +514,23 @@ return false; \ } \ \ + bool first = true; \ V min_val = (V){ 0 }; \ - 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)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - 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 (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (first) \ + { \ + min_val = _set_->buffer[i].value; \ + first = false; \ + } \ + else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) \ + { \ + min_val = _set_->buffer[i].value; \ + } \ + } \ } \ \ if (value) \ @@ -631,13 +639,19 @@ 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)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - CMC_(PFX, _insert_many) \ - (_new_set_, CMC_(PFX, _iter_value)(&iter), CMC_(PFX, _iter_multiplicity)(&iter)); \ + if (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + V value = _set_->buffer[i].value; \ + size_t multiplicity = _set_->buffer[i].multiplicity; \ +\ + /* TODO check this for possible errors where entry == NULL */ \ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_new_set_, value, NULL); \ + \ + entry->multiplicity = multiplicity;\ + /* Setting cardinality not required, _new_set_ is temporary */\ + } \ } \ \ if (_set_->count != _new_set_->count) \ @@ -729,17 +743,26 @@ if (_set1_->count == 0) \ return true; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + /* Optimize loop using the smallest hashtable */ \ + struct SNAME *_set_a_; \ + struct SNAME *_set_b_; \ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; \ + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; \ +\ + for (size_t i = 0; i < _set_a_->capacity; i++) \ { \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set2_, CMC_(PFX, _iter_value)(&iter)); \ + if (_set_a_->buffer[i].state == CMC_ES_FILLED) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_set_a_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *entry_b = CMC_(PFX, _impl_get_entry)(_set_b_, entry_a->value); \ \ - if (!entry) \ - return false; \ + if (!entry_b) \ + return false; \ \ - if (entry->multiplicity != CMC_(PFX, _iter_multiplicity)(&iter)) \ - return false; \ + if (entry_a->multiplicity != entry_b->multiplicity) \ + return false; \ + } \ } \ \ return true; \ @@ -762,14 +785,16 @@ /* something with it. This function only guarantees that there is */ \ /* a valid entry for a given value */ \ \ - *new_node = false; \ + if (new_node)\ + *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 (new_node)\ + *new_node = true; \ \ if (CMC_(PFX, _full)(_set_)) \ { \ diff --git a/tests/src/cmc/hashbidimap.c b/tests/src/cmc/hashbidimap.c index c7a1b70..1d853c5 100644 --- a/tests/src/cmc/hashbidimap.c +++ b/tests/src/cmc/hashbidimap.c @@ -177,7 +177,7 @@ _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } - if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) + if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) goto success; if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) { diff --git a/tests/src/cmc/hashmap.c b/tests/src/cmc/hashmap.c index 20f99e5..d4eb005 100644 --- a/tests/src/cmc/hashmap.c +++ b/tests/src/cmc/hashmap.c @@ -201,23 +201,20 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 0; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; - 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++) + for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { - if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) + if (first) + { + max_key = _map_->buffer[i].key; + max_val = _map_->buffer[i].value; + first = 0; + } + else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) { max_key = _map_->buffer[i].key; max_val = _map_->buffer[i].value; @@ -240,23 +237,20 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t min_key = (size_t){ 0 }; size_t min_val = (size_t){ 0 }; - 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++) + for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { - if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) + if (first) + { + min_key = _map_->buffer[i].key; + min_val = _map_->buffer[i].value; + first = 0; + } + else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) { min_key = _map_->buffer[i].key; min_val = _map_->buffer[i].value; diff --git a/tests/src/cmc/hashmultiset.c b/tests/src/cmc/hashmultiset.c index 6aa25a2..64d656a 100644 --- a/tests/src/cmc/hashmultiset.c +++ b/tests/src/cmc/hashmultiset.c @@ -218,16 +218,22 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t max_val = (size_t){ 0 }; - struct hashmultiset_iter iter = hms_iter_start(_set_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t result = hms_iter_value(&iter); - size_t index = hms_iter_index(&iter); - if (index == 0) - max_val = result; - else if (_set_->f_val->cmp(result, max_val) > 0) - max_val = result; + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + max_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) + { + max_val = _set_->buffer[i].value; + } + } } if (value) *value = max_val; @@ -244,16 +250,22 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t min_val = (size_t){ 0 }; - struct hashmultiset_iter iter = hms_iter_start(_set_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t result = hms_iter_value(&iter); - size_t index = hms_iter_index(&iter); - if (index == 0) - min_val = result; - else if (_set_->f_val->cmp(result, min_val) < 0) - min_val = result; + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + min_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) + { + min_val = _set_->buffer[i].value; + } + } } if (value) *value = min_val; @@ -335,10 +347,15 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity) _set_->flag = CMC_FLAG_ERROR; return 0; } - struct hashmultiset_iter iter = hms_iter_start(_set_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - hms_insert_many(_new_set_, hms_iter_value(&iter), hms_iter_multiplicity(&iter)); + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + size_t value = _set_->buffer[i].value; + size_t multiplicity = _set_->buffer[i].multiplicity; + struct hashmultiset_entry *entry = hms_impl_insert_and_return(_new_set_, value, ((void *)0)); + entry->multiplicity = multiplicity; + } } if (_set_->count != _new_set_->count) { @@ -407,14 +424,21 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) return 0; if (_set1_->count == 0) return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + struct hashmultiset *_set_a_; + struct hashmultiset *_set_b_; + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; + for (size_t i = 0; i < _set_a_->capacity; i++) { - struct hashmultiset_entry *entry = hms_impl_get_entry(_set2_, hms_iter_value(&iter)); - if (!entry) - return 0; - if (entry->multiplicity != hms_iter_multiplicity(&iter)) - return 0; + if (_set_a_->buffer[i].state == CMC_ES_FILLED) + { + struct hashmultiset_entry *entry_a = &(_set_a_->buffer[i]); + struct hashmultiset_entry *entry_b = hms_impl_get_entry(_set_b_, entry_a->value); + if (!entry_b) + return 0; + if (entry_a->multiplicity != entry_b->multiplicity) + return 0; + } } return 1; } @@ -427,11 +451,13 @@ 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) { - *new_node = 0; + if (new_node) + *new_node = 0; struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); if (entry != ((void *)0)) return entry; - *new_node = 1; + if (new_node) + *new_node = 1; if (hms_full(_set_)) { if (!hms_resize(_set_, _set_->capacity + 1)) From f1ab010701fd637e44d8f74c4a96f72237b5c91d Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 1 Jul 2020 23:55:30 -0300 Subject: [PATCH 06/20] Update README and github action --- .github/workflows/test_suit.yml | 8 +++++++- README.md | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test_suit.yml b/.github/workflows/test_suit.yml index e60a5df..43c680b 100644 --- a/.github/workflows/test_suit.yml +++ b/.github/workflows/test_suit.yml @@ -10,7 +10,13 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup Environment - run: sudo apt install make valgrind gcc python + run: sudo apt install make valgrind gcc python3.8 + - name: Versions + run: | + gcc --version \ + make --version \ + valgrind --version \ + python --version \ - name: Test Suite run: python autogen.py -e -b -r -nf # - name: Valgrind Test diff --git a/README.md b/README.md index 239129e..cc0f98b 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,16 @@

LinkToRepo + Stars LinkToDocs

License - Version + Version travis-ci codecov - test_suit + test_suit

## Table of Contents From b6343b4857356de2910d32a29560b269b7a16e2b Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 6 Jul 2020 22:38:15 -0300 Subject: [PATCH 07/20] HashSet no longer depends on ITER --- src/cmc/hashmap.h | 4 ++ src/cmc/hashset.h | 81 ++++++++++++++++++++++++----------------- tests/src/cmc/hashmap.c | 4 +- tests/src/cmc/hashset.c | 70 ++++++++++++++++++++++------------- 4 files changed, 98 insertions(+), 61 deletions(-) diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 747d516..8b45349 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -487,6 +487,8 @@ *key = max_key; \ if (value) \ *value = max_val; \ +\ + _map_->flag = CMC_FLAG_OK; \ \ CMC_CALLBACKS_CALL(_map_, read); \ \ @@ -527,6 +529,8 @@ *key = min_key; \ if (value) \ *value = min_val; \ +\ + _map_->flag = CMC_FLAG_OK; \ \ CMC_CALLBACKS_CALL(_map_, read); \ \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 35b2fa9..5e22961 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -378,19 +378,23 @@ return false; \ } \ \ + bool first = true; \ V max_val = (V){ 0 }; \ - 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)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - 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 (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (first) \ + { \ + max_val = _set_->buffer[i].value; \ + first = false; \ + } \ + else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) \ + { \ + max_val = _set_->buffer[i].value; \ + } \ + } \ } \ \ if (value) \ @@ -411,19 +415,23 @@ return false; \ } \ \ + bool first = true; \ V min_val = (V){ 0 }; \ - 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)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - 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 (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (first) \ + { \ + min_val = _set_->buffer[i].value; \ + first = false; \ + } \ + else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) \ + { \ + min_val = _set_->buffer[i].value; \ + } \ + } \ } \ \ if (value) \ @@ -513,15 +521,15 @@ 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)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - V value = CMC_(PFX, _iter_value)(&iter); \ + if (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + V value = _set_->buffer[i].value; \ \ - /* TODO check for error */ \ - CMC_(PFX, _insert)(_new_set_, value); \ + /* TODO check this for possible errors */ \ + CMC_(PFX, _insert)(_new_set_, value); \ + } \ } \ \ /* Unlikely */ \ @@ -606,16 +614,21 @@ if (_set1_->count != _set2_->count) \ return false; \ \ - if (_set1_->count == 0) \ - return true; \ + /* Optimize loop using the smallest hashtable */ \ + struct SNAME *_set_a_; \ + struct SNAME *_set_b_; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; \ + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; \ \ - /* TODO optimize this loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _set_a_->capacity; i++) \ { \ - if (CMC_(PFX, _impl_get_entry)(_set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ - return false; \ + if (_set_a_->buffer[i].state == CMC_ES_FILLED) \ + { \ + \ + if (!CMC_(PFX, _impl_get_entry)(_set_b_, _set_a_->buffer[i].value))\ + return false;\ + } \ } \ \ return true; \ diff --git a/tests/src/cmc/hashmap.c b/tests/src/cmc/hashmap.c index d4eb005..abb8bf0 100644 --- a/tests/src/cmc/hashmap.c +++ b/tests/src/cmc/hashmap.c @@ -201,7 +201,7 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - _Bool first = 0; + _Bool first = 1; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) @@ -225,6 +225,7 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) *key = max_key; if (value) *value = max_val; + _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read(); ; @@ -261,6 +262,7 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) *key = min_key; if (value) *value = min_val; + _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read(); ; diff --git a/tests/src/cmc/hashset.c b/tests/src/cmc/hashset.c index e0605f1..0594d98 100644 --- a/tests/src/cmc/hashset.c +++ b/tests/src/cmc/hashset.c @@ -164,16 +164,22 @@ _Bool hs_max(struct hashset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t max_val = (size_t){ 0 }; - struct hashset_iter iter = hs_iter_start(_set_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t result = hs_iter_value(&iter); - size_t index = hs_iter_index(&iter); - if (index == 0) - max_val = result; - else if (_set_->f_val->cmp(result, max_val) > 0) - max_val = result; + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + max_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) + { + max_val = _set_->buffer[i].value; + } + } } if (value) *value = max_val; @@ -190,16 +196,22 @@ _Bool hs_min(struct hashset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t min_val = (size_t){ 0 }; - struct hashset_iter iter = hs_iter_start(_set_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t result = hs_iter_value(&iter); - size_t index = hs_iter_index(&iter); - if (index == 0) - min_val = result; - else if (_set_->f_val->cmp(result, min_val) < 0) - min_val = result; + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + min_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) + { + min_val = _set_->buffer[i].value; + } + } } if (value) *value = min_val; @@ -266,11 +278,13 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity) _set_->flag = CMC_FLAG_ALLOC; return 0; } - struct hashset_iter iter = hs_iter_start(_set_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t value = hs_iter_value(&iter); - hs_insert(_new_set_, value); + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + size_t value = _set_->buffer[i].value; + hs_insert(_new_set_, value); + } } if (_set_->count != _new_set_->count) { @@ -333,13 +347,17 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; - if (_set1_->count == 0) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + struct hashset *_set_a_; + struct hashset *_set_b_; + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; + for (size_t i = 0; i < _set_a_->capacity; i++) { - if (hs_impl_get_entry(_set2_, hs_iter_value(&iter)) == ((void *)0)) - return 0; + if (_set_a_->buffer[i].state == CMC_ES_FILLED) + { + if (!hs_impl_get_entry(_set_b_, _set_a_->buffer[i].value)) + return 0; + } } return 1; } From 209d45be5d7c256307a41a8ae50fa1690d55f0d8 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 8 Jul 2020 23:00:24 -0300 Subject: [PATCH 08/20] TreeMap no longer depends on ITER --- src/cmc/hashmultiset.h | 10 ++--- src/cmc/hashset.h | 6 +-- src/cmc/treemap.h | 86 ++++++++++++++++++++++++++++++++++------- tests/src/cmc/treemap.c | 70 +++++++++++++++++++++++++++------ tests/unt/cmc/treemap.h | 3 ++ 5 files changed, 143 insertions(+), 32 deletions(-) diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index 8cfff7d..367de32 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -648,9 +648,9 @@ \ /* TODO check this for possible errors where entry == NULL */ \ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_new_set_, value, NULL); \ - \ - entry->multiplicity = multiplicity;\ - /* Setting cardinality not required, _new_set_ is temporary */\ +\ + entry->multiplicity = multiplicity; \ + /* Setting cardinality not required, _new_set_ is temporary */ \ } \ } \ \ @@ -785,7 +785,7 @@ /* something with it. This function only guarantees that there is */ \ /* a valid entry for a given value */ \ \ - if (new_node)\ + if (new_node) \ *new_node = false; \ \ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \ @@ -793,7 +793,7 @@ if (entry != NULL) \ return entry; \ \ - if (new_node)\ + if (new_node) \ *new_node = true; \ \ if (CMC_(PFX, _full)(_set_)) \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 5e22961..cc707a2 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -625,9 +625,9 @@ { \ if (_set_a_->buffer[i].state == CMC_ES_FILLED) \ { \ - \ - if (!CMC_(PFX, _impl_get_entry)(_set_b_, _set_a_->buffer[i].value))\ - return false;\ +\ + if (!CMC_(PFX, _impl_get_entry)(_set_b_, _set_a_->buffer[i].value)) \ + return false; \ } \ } \ \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index 9f93cfb..bdc0fa6 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -688,25 +688,57 @@ return NULL; \ } \ \ - /* TODO turn this into a normal loop */ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + struct CMC_DEF_NODE(SNAME) *root = _map_->root; \ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + bool left_done = false; \ +\ + while (root) \ { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - V value = CMC_(PFX, _iter_value)(&iter); \ + if (!left_done) \ + { \ + while (root->left) \ + root = root->left; \ + } \ +\ + K key; \ + V value; \ \ if (_map_->f_key->cpy) \ - key = _map_->f_key->cpy(key); \ + key = _map_->f_key->cpy(root->key); \ + else \ + key = root->key; \ if (_map_->f_val->cpy) \ - value = _map_->f_val->cpy(value); \ + value = _map_->f_val->cpy(root->value); \ + else \ + value = root->value; \ \ /* TODO check this for errors */ \ CMC_(PFX, _insert)(result, key, value); \ +\ + 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; \ } \ \ - CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ _map_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ \ return result; \ } \ @@ -719,18 +751,46 @@ 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_); \ + struct CMC_DEF_NODE(SNAME) *root = _map1_->root; \ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + bool left_done = false; \ +\ + while (root) \ { \ - struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map2_, CMC_(PFX, _iter_key)(&iter)); \ + if (!left_done) \ + { \ + while (root->left) \ + root = root->left; \ + } \ +\ + /* TODO this can be optimized by doing two in-order traversals */\ + struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map2_, root->key); \ \ if (node == NULL) \ return false; \ \ - if (_map1_->f_val->cmp(node->value, CMC_(PFX, _iter_value)(&iter)) != 0) \ + if (_map1_->f_val->cmp(node->value, root->value) != 0) \ 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; \ diff --git a/tests/src/cmc/treemap.c b/tests/src/cmc/treemap.c index 6c495e7..a019f9b 100644 --- a/tests/src/cmc/treemap.c +++ b/tests/src/cmc/treemap.c @@ -400,19 +400,45 @@ struct treemap *tm_copy_of(struct treemap *_map_) _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } - struct treemap_iter iter = tm_iter_start(_map_); - for (; !tm_iter_at_end(&iter); tm_iter_next(&iter)) + struct treemap_node *root = _map_->root; + _Bool left_done = 0; + while (root) { - size_t key = tm_iter_key(&iter); - size_t value = tm_iter_value(&iter); + if (!left_done) + { + while (root->left) + root = root->left; + } + size_t key; + size_t value; if (_map_->f_key->cpy) - key = _map_->f_key->cpy(key); + key = _map_->f_key->cpy(root->key); + else + key = root->key; if (_map_->f_val->cpy) - value = _map_->f_val->cpy(value); + value = _map_->f_val->cpy(root->value); + else + value = root->value; tm_insert(result, key, value); + 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; } - (result)->callbacks = _map_->callbacks; _map_->flag = CMC_FLAG_OK; + (result)->callbacks = _map_->callbacks; return result; } _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) @@ -421,14 +447,36 @@ _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; - struct treemap_iter iter = tm_iter_start(_map1_); - for (; !tm_iter_at_end(&iter); tm_iter_next(&iter)) + struct treemap_node *root = _map1_->root; + _Bool left_done = 0; + while (root) { - struct treemap_node *node = tm_impl_get_node(_map2_, tm_iter_key(&iter)); + if (!left_done) + { + while (root->left) + root = root->left; + } + struct treemap_node *node = tm_impl_get_node(_map2_, root->key); if (node == ((void *)0)) return 0; - if (_map1_->f_val->cmp(node->value, tm_iter_value(&iter)) != 0) + if (_map1_->f_val->cmp(node->value, root->value) != 0) 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; } diff --git a/tests/unt/cmc/treemap.h b/tests/unt/cmc/treemap.h index 014ac02..90e2483 100644 --- a/tests/unt/cmc/treemap.h +++ b/tests/unt/cmc/treemap.h @@ -116,6 +116,9 @@ CMC_CREATE_UNIT(CMCTreeMap, true, { tm_get_ref(map, 1); cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); + for (size_t i = 0; i < 100; i++) + cmc_assert(tm_insert(map, i, i)); + // copy_of map->flag = CMC_FLAG_ERROR; struct treemap *map2 = tm_copy_of(map); From 61aa8b879e59c78dd1fd0c1ae905320bfc9fbfb5 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 8 Jul 2020 23:29:53 -0300 Subject: [PATCH 09/20] Trying to fix CI, once again --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index b001f94..6de5372 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,9 +12,9 @@ addons: - cmake - python3.8 script: - - sudo ln -s /usr/bin/gcc-9 /usr/local/bin/gcc - - sudo ln -s /usr/bin/gcov-9 /usr/local/bin/gcov - - sudo ln -s /usr/bin/python3.8 /usr/local/bin/python + - sudo ln -s /usr/bin/gcc-9 /usr/bin/gcc + - sudo ln -s /usr/bin/gcov-9 /usr/bin/gcov + - sudo ln -s /usr/bin/python3.8 /usr/bin/python - gcc --version - gcov --version - python --version From 6cb2160456f1b3f0ad789c004b8b221993721fc2 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 8 Jul 2020 23:43:56 -0300 Subject: [PATCH 10/20] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6de5372..6f0bd4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ addons: - cmake - python3.8 script: + - sudo rm -f /usr/bin/gcc /usr/bin/gcov /usr/bin/python - sudo ln -s /usr/bin/gcc-9 /usr/bin/gcc - sudo ln -s /usr/bin/gcov-9 /usr/bin/gcov - sudo ln -s /usr/bin/python3.8 /usr/bin/python From 2424f0d8cd29d8b4763e0f4852d5a45e0e815dec Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sat, 26 Sep 2020 13:35:28 -0300 Subject: [PATCH 11/20] New project architecture in progress: renaming, refactoring and adjustments --- autogen.py | 69 +- src/{cmc/bitset.h => cmc_bitset.h} | 6 +- src/{cmc/deque.h => cmc_deque.h} | 4 +- src/{cmc/hashbidimap.h => cmc_hashbidimap.h} | 6 +- src/{cmc/hashmap.h => cmc_hashmap.h} | 6 +- .../hashmultimap.h => cmc_hashmultimap.h} | 6 +- .../hashmultiset.h => cmc_hashmultiset.h} | 6 +- src/{cmc/hashset.h => cmc_hashset.h} | 6 +- src/{cmc/heap.h => cmc_heap.h} | 6 +- .../intervalheap.h => cmc_intervalheap.h} | 4 +- src/{cmc/linkedlist.h => cmc_linkedlist.h} | 4 +- src/{cmc/list.h => cmc_list.h} | 4 +- src/{cmc/queue.h => cmc_queue.h} | 4 +- src/{cmc/sortedlist.h => cmc_sortedlist.h} | 4 +- src/{cmc/stack.h => cmc_stack.h} | 4 +- src/{cmc/treemap.h => cmc_treemap.h} | 6 +- src/{cmc/treeset.h => cmc_treeset.h} | 4 +- src/{cor/alloc.h => cor_alloc.h} | 2 +- src/{cor/bitset.h => cor_bitset.h} | 4 +- src/{cor/callbacks.h => cor_callbacks.h} | 2 +- src/{cor/core.h => cor_core.h} | 10 +- src/{cor/flags.h => cor_flags.h} | 4 +- src/{cor/ftable.h => cor_ftable.h} | 2 +- src/{cor/hashtable.h => cor_hashtable.h} | 4 +- src/{cor/heap.h => cor_heap.h} | 2 +- src/{ext/cmc/bitset.h => ext_cmc_bitset.h} | 4 +- src/{ext/cmc/deque.h => ext_cmc_deque.h} | 4 +- .../hashbidimap.h => ext_cmc_hashbidimap.h} | 4 +- src/{ext/cmc/hashmap.h => ext_cmc_hashmap.h} | 4 +- .../hashmultimap.h => ext_cmc_hashmultimap.h} | 4 +- .../hashmultiset.h => ext_cmc_hashmultiset.h} | 4 +- src/{ext/cmc/hashset.h => ext_cmc_hashset.h} | 4 +- src/{ext/cmc/heap.h => ext_cmc_heap.h} | 4 +- .../intervalheap.h => ext_cmc_intervalheap.h} | 4 +- .../cmc/linkedlist.h => ext_cmc_linkedlist.h} | 4 +- src/{ext/cmc/list.h => ext_cmc_list.h} | 4 +- src/{ext/cmc/queue.h => ext_cmc_queue.h} | 4 +- .../cmc/sortedlist.h => ext_cmc_sortedlist.h} | 4 +- src/{ext/cmc/stack.h => ext_cmc_stack.h} | 4 +- src/{ext/cmc/treemap.h => ext_cmc_treemap.h} | 4 +- src/{ext/cmc/treeset.h => ext_cmc_treeset.h} | 4 +- src/macro_collections.h | 96 +- src/{utl/assert.h => utl_assert.h} | 4 +- src/{utl/foreach.h => utl_foreach.h} | 4 +- src/{utl/futils.h => utl_futils.h} | 2 +- src/{utl/log.h => utl_log.h} | 4 +- src/{utl/mutex.h => utl_mutex.h} | 4 +- src/{utl/test.h => utl_test.h} | 8 +- src/{utl/thread.h => utl_thread.h} | 4 +- src/{utl/timer.h => utl_timer.h} | 2 +- tests/codecov.c | 104 +- tests/include/cmc/bitset.h | 44 - tests/include/cmc/deque.h | 78 -- tests/include/cmc/hashbidimap.h | 101 -- tests/include/cmc/hashmap.h | 100 -- tests/include/cmc/hashmultimap.h | 102 -- tests/include/cmc/hashmultiset.h | 98 -- tests/include/cmc/hashset.h | 88 -- tests/include/cmc/heap.h | 68 -- tests/include/cmc/intervalheap.h | 72 -- tests/include/cmc/linkedlist.h | 92 -- tests/include/cmc/list.h | 82 -- tests/include/cmc/queue.h | 71 -- tests/include/cmc/sortedlist.h | 72 -- tests/include/cmc/stack.h | 68 -- tests/include/cmc/treemap.h | 92 -- tests/include/cmc/treeset.h | 84 -- tests/include/tst_cmc_bitset.h | 11 + tests/include/tst_cmc_deque.h | 11 + tests/include/tst_cmc_hashbidimap.h | 11 + tests/include/tst_cmc_hashmap.h | 11 + tests/include/tst_cmc_hashmultimap.h | 11 + tests/include/tst_cmc_hashmultiset.h | 11 + tests/include/tst_cmc_hashset.h | 11 + tests/include/tst_cmc_heap.h | 11 + tests/include/tst_cmc_intervalheap.h | 11 + tests/include/tst_cmc_linkedlist.h | 11 + tests/include/tst_cmc_list.h | 11 + tests/include/tst_cmc_queue.h | 11 + tests/include/tst_cmc_sortedlist.h | 11 + tests/include/tst_cmc_stack.h | 11 + tests/include/tst_cmc_treemap.h | 11 + tests/include/tst_cmc_treeset.h | 11 + tests/main.c | 40 +- tests/src/cmc/bitset.c | 294 ------ tests/src/cmc/deque.c | 516 ---------- tests/src/cmc/hashbidimap.c | 856 --------------- tests/src/cmc/hashmap.c | 788 -------------- tests/src/cmc/hashmultimap.c | 931 ----------------- tests/src/cmc/hashmultiset.c | 972 ------------------ tests/src/cmc/hashset.c | 773 -------------- tests/src/cmc/heap.c | 424 -------- tests/src/cmc/intervalheap.c | 686 ------------ tests/src/cmc/linkedlist.c | 683 ------------ tests/src/cmc/list.c | 643 ------------ tests/src/cmc/queue.c | 431 -------- tests/src/cmc/sortedlist.c | 512 --------- tests/src/cmc/stack.c | 367 ------- tests/src/cmc/treemap.c | 852 --------------- tests/src/cmc/treeset.c | 841 --------------- tests/src/tst_cmc_bitset.c | 7 + tests/src/tst_cmc_deque.c | 7 + tests/src/tst_cmc_hashbidimap.c | 7 + tests/src/tst_cmc_hashmap.c | 7 + tests/src/tst_cmc_hashmultimap.c | 7 + tests/src/tst_cmc_hashmultiset.c | 7 + tests/src/tst_cmc_hashset.c | 7 + tests/src/tst_cmc_heap.c | 7 + tests/src/tst_cmc_intervalheap.c | 7 + tests/src/tst_cmc_linkedlist.c | 7 + tests/src/tst_cmc_list.c | 7 + tests/src/tst_cmc_queue.c | 7 + tests/src/tst_cmc_sortedlist.c | 7 + tests/src/tst_cmc_stack.c | 7 + tests/src/tst_cmc_treemap.c | 7 + tests/src/tst_cmc_treeset.c | 7 + tests/unt/{cmc/bitset.h => unt_cmc_bitset.h} | 4 +- tests/unt/{cmc/deque.h => unt_cmc_deque.h} | 4 +- .../hashbidimap.h => unt_cmc_hashbidimap.h} | 4 +- .../unt/{cmc/hashmap.h => unt_cmc_hashmap.h} | 4 +- .../hashmultimap.h => unt_cmc_hashmultimap.h} | 4 +- .../hashmultiset.h => unt_cmc_hashmultiset.h} | 4 +- .../unt/{cmc/hashset.h => unt_cmc_hashset.h} | 4 +- tests/unt/{cmc/heap.h => unt_cmc_heap.h} | 4 +- .../intervalheap.h => unt_cmc_intervalheap.h} | 4 +- .../linkedlist.h => unt_cmc_linkedlist.h} | 4 +- tests/unt/{cmc/list.h => unt_cmc_list.h} | 4 +- tests/unt/{cmc/queue.h => unt_cmc_queue.h} | 4 +- .../sortedlist.h => unt_cmc_sortedlist.h} | 4 +- tests/unt/{cmc/stack.h => unt_cmc_stack.h} | 4 +- .../unt/{cmc/treemap.h => unt_cmc_treemap.h} | 4 +- .../unt/{cmc/treeset.h => unt_cmc_treeset.h} | 4 +- .../unt/{utl/foreach.h => unt_utl_foreach.h} | 34 +- tests/unt/utl.h | 10 +- 134 files changed, 596 insertions(+), 12196 deletions(-) rename src/{cmc/bitset.h => cmc_bitset.h} (99%) rename src/{cmc/deque.h => cmc_deque.h} (99%) rename src/{cmc/hashbidimap.h => cmc_hashbidimap.h} (99%) rename src/{cmc/hashmap.h => cmc_hashmap.h} (99%) rename src/{cmc/hashmultimap.h => cmc_hashmultimap.h} (99%) rename src/{cmc/hashmultiset.h => cmc_hashmultiset.h} (99%) rename src/{cmc/hashset.h => cmc_hashset.h} (99%) rename src/{cmc/heap.h => cmc_heap.h} (99%) rename src/{cmc/intervalheap.h => cmc_intervalheap.h} (99%) rename src/{cmc/linkedlist.h => cmc_linkedlist.h} (99%) rename src/{cmc/list.h => cmc_list.h} (99%) rename src/{cmc/queue.h => cmc_queue.h} (99%) rename src/{cmc/sortedlist.h => cmc_sortedlist.h} (99%) rename src/{cmc/stack.h => cmc_stack.h} (99%) rename src/{cmc/treemap.h => cmc_treemap.h} (99%) rename src/{cmc/treeset.h => cmc_treeset.h} (99%) rename src/{cor/alloc.h => cor_alloc.h} (98%) rename src/{cor/bitset.h => cor_bitset.h} (96%) rename src/{cor/callbacks.h => cor_callbacks.h} (98%) rename src/{cor/core.h => cor_core.h} (95%) rename src/{cor/flags.h => cor_flags.h} (97%) rename src/{cor/ftable.h => cor_ftable.h} (97%) rename src/{cor/hashtable.h => cor_hashtable.h} (97%) rename src/{cor/heap.h => cor_heap.h} (97%) rename src/{ext/cmc/bitset.h => ext_cmc_bitset.h} (92%) rename src/{ext/cmc/deque.h => ext_cmc_deque.h} (99%) rename src/{ext/cmc/hashbidimap.h => ext_cmc_hashbidimap.h} (98%) rename src/{ext/cmc/hashmap.h => ext_cmc_hashmap.h} (99%) rename src/{ext/cmc/hashmultimap.h => ext_cmc_hashmultimap.h} (99%) rename src/{ext/cmc/hashmultiset.h => ext_cmc_hashmultiset.h} (99%) rename src/{ext/cmc/hashset.h => ext_cmc_hashset.h} (99%) rename src/{ext/cmc/heap.h => ext_cmc_heap.h} (99%) rename src/{ext/cmc/intervalheap.h => ext_cmc_intervalheap.h} (99%) rename src/{ext/cmc/linkedlist.h => ext_cmc_linkedlist.h} (99%) rename src/{ext/cmc/list.h => ext_cmc_list.h} (99%) rename src/{ext/cmc/queue.h => ext_cmc_queue.h} (99%) rename src/{ext/cmc/sortedlist.h => ext_cmc_sortedlist.h} (99%) rename src/{ext/cmc/stack.h => ext_cmc_stack.h} (99%) rename src/{ext/cmc/treemap.h => ext_cmc_treemap.h} (99%) rename src/{ext/cmc/treeset.h => ext_cmc_treeset.h} (99%) rename src/{utl/assert.h => utl_assert.h} (99%) rename src/{utl/foreach.h => utl_foreach.h} (95%) rename src/{utl/futils.h => utl_futils.h} (99%) rename src/{utl/log.h => utl_log.h} (99%) rename src/{utl/mutex.h => utl_mutex.h} (99%) rename src/{utl/test.h => utl_test.h} (98%) rename src/{utl/thread.h => utl_thread.h} (98%) rename src/{utl/timer.h => utl_timer.h} (98%) delete mode 100644 tests/include/cmc/bitset.h delete mode 100644 tests/include/cmc/deque.h delete mode 100644 tests/include/cmc/hashbidimap.h delete mode 100644 tests/include/cmc/hashmap.h delete mode 100644 tests/include/cmc/hashmultimap.h delete mode 100644 tests/include/cmc/hashmultiset.h delete mode 100644 tests/include/cmc/hashset.h delete mode 100644 tests/include/cmc/heap.h delete mode 100644 tests/include/cmc/intervalheap.h delete mode 100644 tests/include/cmc/linkedlist.h delete mode 100644 tests/include/cmc/list.h delete mode 100644 tests/include/cmc/queue.h delete mode 100644 tests/include/cmc/sortedlist.h delete mode 100644 tests/include/cmc/stack.h delete mode 100644 tests/include/cmc/treemap.h delete mode 100644 tests/include/cmc/treeset.h create mode 100644 tests/include/tst_cmc_bitset.h create mode 100644 tests/include/tst_cmc_deque.h create mode 100644 tests/include/tst_cmc_hashbidimap.h create mode 100644 tests/include/tst_cmc_hashmap.h create mode 100644 tests/include/tst_cmc_hashmultimap.h create mode 100644 tests/include/tst_cmc_hashmultiset.h create mode 100644 tests/include/tst_cmc_hashset.h create mode 100644 tests/include/tst_cmc_heap.h create mode 100644 tests/include/tst_cmc_intervalheap.h create mode 100644 tests/include/tst_cmc_linkedlist.h create mode 100644 tests/include/tst_cmc_list.h create mode 100644 tests/include/tst_cmc_queue.h create mode 100644 tests/include/tst_cmc_sortedlist.h create mode 100644 tests/include/tst_cmc_stack.h create mode 100644 tests/include/tst_cmc_treemap.h create mode 100644 tests/include/tst_cmc_treeset.h delete mode 100644 tests/src/cmc/bitset.c delete mode 100644 tests/src/cmc/deque.c delete mode 100644 tests/src/cmc/hashbidimap.c delete mode 100644 tests/src/cmc/hashmap.c delete mode 100644 tests/src/cmc/hashmultimap.c delete mode 100644 tests/src/cmc/hashmultiset.c delete mode 100644 tests/src/cmc/hashset.c delete mode 100644 tests/src/cmc/heap.c delete mode 100644 tests/src/cmc/intervalheap.c delete mode 100644 tests/src/cmc/linkedlist.c delete mode 100644 tests/src/cmc/list.c delete mode 100644 tests/src/cmc/queue.c delete mode 100644 tests/src/cmc/sortedlist.c delete mode 100644 tests/src/cmc/stack.c delete mode 100644 tests/src/cmc/treemap.c delete mode 100644 tests/src/cmc/treeset.c create mode 100644 tests/src/tst_cmc_bitset.c create mode 100644 tests/src/tst_cmc_deque.c create mode 100644 tests/src/tst_cmc_hashbidimap.c create mode 100644 tests/src/tst_cmc_hashmap.c create mode 100644 tests/src/tst_cmc_hashmultimap.c create mode 100644 tests/src/tst_cmc_hashmultiset.c create mode 100644 tests/src/tst_cmc_hashset.c create mode 100644 tests/src/tst_cmc_heap.c create mode 100644 tests/src/tst_cmc_intervalheap.c create mode 100644 tests/src/tst_cmc_linkedlist.c create mode 100644 tests/src/tst_cmc_list.c create mode 100644 tests/src/tst_cmc_queue.c create mode 100644 tests/src/tst_cmc_sortedlist.c create mode 100644 tests/src/tst_cmc_stack.c create mode 100644 tests/src/tst_cmc_treemap.c create mode 100644 tests/src/tst_cmc_treeset.c rename tests/unt/{cmc/bitset.h => unt_cmc_bitset.h} (99%) rename tests/unt/{cmc/deque.h => unt_cmc_deque.h} (99%) rename tests/unt/{cmc/hashbidimap.h => unt_cmc_hashbidimap.h} (99%) rename tests/unt/{cmc/hashmap.h => unt_cmc_hashmap.h} (99%) rename tests/unt/{cmc/hashmultimap.h => unt_cmc_hashmultimap.h} (99%) rename tests/unt/{cmc/hashmultiset.h => unt_cmc_hashmultiset.h} (99%) rename tests/unt/{cmc/hashset.h => unt_cmc_hashset.h} (99%) rename tests/unt/{cmc/heap.h => unt_cmc_heap.h} (99%) rename tests/unt/{cmc/intervalheap.h => unt_cmc_intervalheap.h} (99%) rename tests/unt/{cmc/linkedlist.h => unt_cmc_linkedlist.h} (99%) rename tests/unt/{cmc/list.h => unt_cmc_list.h} (99%) rename tests/unt/{cmc/queue.h => unt_cmc_queue.h} (99%) rename tests/unt/{cmc/sortedlist.h => unt_cmc_sortedlist.h} (99%) rename tests/unt/{cmc/stack.h => unt_cmc_stack.h} (99%) rename tests/unt/{cmc/treemap.h => unt_cmc_treemap.h} (99%) rename tests/unt/{cmc/treeset.h => unt_cmc_treeset.h} (99%) rename tests/unt/{utl/foreach.h => unt_utl_foreach.h} (97%) diff --git a/autogen.py b/autogen.py index c160e31..504fdb8 100644 --- a/autogen.py +++ b/autogen.py @@ -24,8 +24,8 @@ from typing import List, Text # In this directory it is assumed that the following files and directories are # included: main.c, codecov.c, unt folder OUTPUT_DIR = './tests' -# All libraries -ALL_LIBS = ['CMC'] +# Where the unit test files are +UNT_DIR = f'{OUTPUT_DIR}/unt' # Directory mapping DIR_MAP = {'HEADER': 'include', 'SOURCE': 'src'} # File extension mapping @@ -70,10 +70,10 @@ GCOV_FLAGS = [] INCLUDE = ['-I', './src'] # Include to the test file headers # const -TINCLUDE = ['-I', f'{INCLUDE_DIR}'] +TINCLUDE = ['-I', f'{INCLUDE_DIR}', '-I', f'{UNT_DIR}'] # Include to code coverage # const -CVINCLUDE = ['-I', INCLUDE_DIR, '-I', SRC_DIR] +CVINCLUDE = ['-I', INCLUDE_DIR, '-I', SRC_DIR, '-I', f'{UNT_DIR}'] # Macro Expansion @@ -92,29 +92,29 @@ TMP_FILE = './main.c' # All collections that can be used for testing COLLECTIONS = [ # header, library, collection, pfx, sname, size, key, val - {'h': '"cmc/bitset.h"', 'LIB': 'CMC', 'COLLECTION': 'BITSET', 'PFX': 'bs', 'SNAME': 'bitset', 'SIZE': '', 'K': '', 'V': '' }, - {'h': '"cmc/deque.h"', 'LIB': 'CMC', 'COLLECTION': 'DEQUE', 'PFX': 'd', 'SNAME': 'deque', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/hashbidimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHBIDIMAP', 'PFX': 'hbm', 'SNAME': 'hashbidimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, - {'h': '"cmc/hashmap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMAP', 'PFX': 'hm', 'SNAME': 'hashmap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, - {'h': '"cmc/hashmultimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMULTIMAP', 'PFX': 'hmm', 'SNAME': 'hashmultimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, - {'h': '"cmc/hashmultiset.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMULTISET', 'PFX': 'hms', 'SNAME': 'hashmultiset', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/hashset.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHSET', 'PFX': 'hs', 'SNAME': 'hashset', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/heap.h"', 'LIB': 'CMC', 'COLLECTION': 'HEAP', 'PFX': 'h', 'SNAME': 'heap', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/intervalheap.h"', 'LIB': 'CMC', 'COLLECTION': 'INTERVALHEAP', 'PFX': 'ih', 'SNAME': 'intervalheap', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/linkedlist.h"', 'LIB': 'CMC', 'COLLECTION': 'LINKEDLIST', 'PFX': 'll', 'SNAME': 'linkedlist', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/list.h"', 'LIB': 'CMC', 'COLLECTION': 'LIST', 'PFX': 'l', 'SNAME': 'list', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/queue.h"', 'LIB': 'CMC', 'COLLECTION': 'QUEUE', 'PFX': 'q', 'SNAME': 'queue', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/sortedlist.h"', 'LIB': 'CMC', 'COLLECTION': 'SORTEDLIST', 'PFX': 'sl', 'SNAME': 'sortedlist', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/stack.h"', 'LIB': 'CMC', 'COLLECTION': 'STACK', 'PFX': 's', 'SNAME': 'stack', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc/treemap.h"', 'LIB': 'CMC', 'COLLECTION': 'TREEMAP', 'PFX': 'tm', 'SNAME': 'treemap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, - {'h': '"cmc/treeset.h"', 'LIB': 'CMC', 'COLLECTION': 'TREESET', 'PFX': 'ts', 'SNAME': 'treeset', 'SIZE': '', 'K': '', 'V': 'size_t'} + {'h': '"cmc_bitset.h"', 'LIB': 'CMC', 'COLLECTION': 'BITSET', 'PFX': 'bs', 'SNAME': 'bitset', 'SIZE': '', 'K': '', 'V': '' }, + {'h': '"cmc_deque.h"', 'LIB': 'CMC', 'COLLECTION': 'DEQUE', 'PFX': 'd', 'SNAME': 'deque', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_hashbidimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHBIDIMAP', 'PFX': 'hbm', 'SNAME': 'hashbidimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, + {'h': '"cmc_hashmap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMAP', 'PFX': 'hm', 'SNAME': 'hashmap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, + {'h': '"cmc_hashmultimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMULTIMAP', 'PFX': 'hmm', 'SNAME': 'hashmultimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, + {'h': '"cmc_hashmultiset.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMULTISET', 'PFX': 'hms', 'SNAME': 'hashmultiset', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_hashset.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHSET', 'PFX': 'hs', 'SNAME': 'hashset', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_heap.h"', 'LIB': 'CMC', 'COLLECTION': 'HEAP', 'PFX': 'h', 'SNAME': 'heap', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_intervalheap.h"', 'LIB': 'CMC', 'COLLECTION': 'INTERVALHEAP', 'PFX': 'ih', 'SNAME': 'intervalheap', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_linkedlist.h"', 'LIB': 'CMC', 'COLLECTION': 'LINKEDLIST', 'PFX': 'll', 'SNAME': 'linkedlist', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_list.h"', 'LIB': 'CMC', 'COLLECTION': 'LIST', 'PFX': 'l', 'SNAME': 'list', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_queue.h"', 'LIB': 'CMC', 'COLLECTION': 'QUEUE', 'PFX': 'q', 'SNAME': 'queue', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_sortedlist.h"', 'LIB': 'CMC', 'COLLECTION': 'SORTEDLIST', 'PFX': 'sl', 'SNAME': 'sortedlist', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_stack.h"', 'LIB': 'CMC', 'COLLECTION': 'STACK', 'PFX': 's', 'SNAME': 'stack', 'SIZE': '', 'K': '', 'V': 'size_t'}, + {'h': '"cmc_treemap.h"', 'LIB': 'CMC', 'COLLECTION': 'TREEMAP', 'PFX': 'tm', 'SNAME': 'treemap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, + {'h': '"cmc_treeset.h"', 'LIB': 'CMC', 'COLLECTION': 'TREESET', 'PFX': 'ts', 'SNAME': 'treeset', 'SIZE': '', 'K': '', 'V': 'size_t'} ] # Just a realy helpfull overview CONFIG = f'''Directory Settings OUTPUT_DIR = {OUTPUT_DIR} - ALL_LIBS = {ALL_LIBS} + UNT_DIR = {UNT_DIR} DIR_MAP = {DIR_MAP} EXT_MAP = {EXT_MAP} BUILD_DIR = {BUILD_DIR} @@ -194,19 +194,11 @@ def assert_structure(): for directory in DIR_MAP.values(): assert_dir(f'{OUTPUT_DIR}/{directory}') - # For each library, create a directory for include and src - for lib in ALL_LIBS: - for directory in DIR_MAP.values(): - assert_dir(f'{OUTPUT_DIR}/{directory}/{lib.lower()}') - assert_dir(BUILD_DIR) assert_dir(OBJ_DIR) assert_dir(BIN_DIR) assert_dir(GCOV_DIR) - for lib in ALL_LIBS: - assert_dir(f'{OBJ_DIR}/{lib.lower()}') - def format_code(source: bool, tests: bool): ''' @@ -223,9 +215,11 @@ def clean_build(cleanfull: bool): Removes all files generated by compilation and code coverage along with folders. ''' # -f prevents 'rm' from failing - execute_command(['rm', '-r', '-f', f'{GCOV_DIR}/*.gcov']) + execute_command(['rm', '-r', '-f', f'./*.gcov']) execute_command(['rm', '-r', '-f', f'{OUTPUT_DIR}/*.exe']) execute_command(['rm', '-r', '-f', BUILD_DIR]) + execute_command(['rm', '-f', './*.gcda']) + execute_command(['rm', '-f', './*.gcno']) if cleanfull: execute_command(['rm', '-r', SRC_DIR]) @@ -265,7 +259,7 @@ def expand_code(): print('Didn\'t match FLAG. Probably because compilation failed.', file=sys.stderr) exit(1) - file = open(f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}', 'w') + file = open(f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/tst_{data["LIB"].lower()}_{data["SNAME"]}.{EXT_MAP[ftype]}', 'w') if ftype == 'HEADER': file.write( @@ -281,7 +275,7 @@ def expand_code(): else: file.write( f''' - #include {data["h"]} + #include {'"tst_' + data["h"][1:]} {match.group("code")} ''') @@ -289,7 +283,7 @@ def expand_code(): file.flush() file.close() - print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}') + print(f'''Generated {'"tst_' + data["h"][1:]: >24} -> {OUTPUT_DIR}/{DIR_MAP[ftype]}/tst_{data["LIB"].lower()}_{data["SNAME"]}.{EXT_MAP[ftype]}''') os.remove(TMP_FILE) @@ -299,7 +293,7 @@ def format_expand(): Format the files outputted by 'expand_code'. ''' cmd = ['clang-format', '--style=file', '--verbose', '-i'] - dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{lib.lower()}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys() for lib in ALL_LIBS] + dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys()] cmd.extend(dirs_to_format) execute_command(cmd) @@ -312,8 +306,8 @@ def build_main(): cmd = [CC] cmd += TINCLUDE # This one needs to go first cmd += INCLUDE - cmd += ['-c', f"{SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c"] - cmd += ['-o', f"{OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o"] + cmd += ['-c', f"{SRC_DIR}/tst_{data['LIB'].lower()}_{data['SNAME']}.c"] + cmd += ['-o', f"{OBJ_DIR}/tst_{data['LIB'].lower()}_{data['SNAME']}.o"] execute_command(cmd) # Build OUTPUT_DIR/main.c @@ -329,7 +323,7 @@ def build_main(): cmd += LFLAGS cmd += ['-o', f'{BIN_DIR}/{MAIN}.exe'] cmd += [f'{OBJ_DIR}/main.o'] - cmd += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS] + cmd += [f'{OBJ_DIR}/tst_{data["LIB"].lower()}_{data["SNAME"]}.o' for data in COLLECTIONS] execute_command(cmd) @@ -490,7 +484,6 @@ if __name__ == '__main__': if args.codecov: require_file(f'{OUTPUT_DIR}/{CODECOV}.c') - require_executable if args.build: build_codecov() if args.run: diff --git a/src/cmc/bitset.h b/src/cmc_bitset.h similarity index 99% rename from src/cmc/bitset.h rename to src/cmc_bitset.h index 4e2ef04..3fb2a91 100644 --- a/src/cmc/bitset.h +++ b/src/cmc_bitset.h @@ -1,5 +1,5 @@ /** - * cmc/bitset.h + * cmc_bitset.h * * Creation Date: 30/04/2020 * @@ -34,12 +34,12 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /* ------------------------------------------------------------------------- * BitSet Implementation * ------------------------------------------------------------------------- */ -#include "../cor/bitset.h" +#include "cor_bitset.h" /** * Core BitSet implementation diff --git a/src/cmc/deque.h b/src/cmc_deque.h similarity index 99% rename from src/cmc/deque.h rename to src/cmc_deque.h index 07c78ec..e2edf40 100644 --- a/src/cmc/deque.h +++ b/src/cmc_deque.h @@ -1,5 +1,5 @@ /** - * cmc/deque.h + * cmc_deque.h * * Creation Date: 20/03/2019 * @@ -34,7 +34,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core Deque implementation diff --git a/src/cmc/hashbidimap.h b/src/cmc_hashbidimap.h similarity index 99% rename from src/cmc/hashbidimap.h rename to src/cmc_hashbidimap.h index 9680303..660301c 100644 --- a/src/cmc/hashbidimap.h +++ b/src/cmc_hashbidimap.h @@ -1,5 +1,5 @@ /** - * cmc/hashbidimap.h + * cmc_hashbidimap.h * * Creation Date: 26/09/2019 * @@ -29,12 +29,12 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /* ------------------------------------------------------------------------- * Hashtable Implementation * ------------------------------------------------------------------------- */ -#include "../cor/hashtable.h" +#include "cor_hashtable.h" /** * Core HashBidiMap implementation diff --git a/src/cmc/hashmap.h b/src/cmc_hashmap.h similarity index 99% rename from src/cmc/hashmap.h rename to src/cmc_hashmap.h index 8b45349..4380585 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc_hashmap.h @@ -1,5 +1,5 @@ /** - * cmc/hashmap.h + * cmc_hashmap.h * * Creation Date: 03/04/2019 * @@ -22,12 +22,12 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /* ------------------------------------------------------------------------- * Hashtable Implementation * ------------------------------------------------------------------------- */ -#include "../cor/hashtable.h" +#include "cor_hashtable.h" /** * Core HashMap implementation diff --git a/src/cmc/hashmultimap.h b/src/cmc_hashmultimap.h similarity index 99% rename from src/cmc/hashmultimap.h rename to src/cmc_hashmultimap.h index 8371e5a..8cd0272 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc_hashmultimap.h @@ -1,5 +1,5 @@ /** - * cmc/hashmultimap.h + * cmc_hashmultimap.h * * Creation Date: 26/04/2019 * @@ -47,12 +47,12 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /* ------------------------------------------------------------------------- * Hashtable Implementation * ------------------------------------------------------------------------- */ -#include "../cor/hashtable.h" +#include "cor_hashtable.h" /** * Core HashMultiMap implementation diff --git a/src/cmc/hashmultiset.h b/src/cmc_hashmultiset.h similarity index 99% rename from src/cmc/hashmultiset.h rename to src/cmc_hashmultiset.h index 367de32..d8587b2 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc_hashmultiset.h @@ -1,5 +1,5 @@ /** - * cmc/hashmultiset.h + * cmc_hashmultiset.h * * Creation Date: 10/04/2019 * @@ -29,12 +29,12 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /* ------------------------------------------------------------------------- * Hashtable Implementation * ------------------------------------------------------------------------- */ -#include "../cor/hashtable.h" +#include "cor_hashtable.h" /** * Core HashMultiSet implementation diff --git a/src/cmc/hashset.h b/src/cmc_hashset.h similarity index 99% rename from src/cmc/hashset.h rename to src/cmc_hashset.h index cc707a2..14f4ae3 100644 --- a/src/cmc/hashset.h +++ b/src/cmc_hashset.h @@ -1,5 +1,5 @@ /** - * cmc/hashset.h + * cmc_hashset.h * * Creation Date: 01/04/2019 * @@ -22,12 +22,12 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /* ------------------------------------------------------------------------- * Hashtable Implementation * ------------------------------------------------------------------------- */ -#include "../cor/hashtable.h" +#include "cor_hashtable.h" /** * Core HashSet implementation diff --git a/src/cmc/heap.h b/src/cmc_heap.h similarity index 99% rename from src/cmc/heap.h rename to src/cmc_heap.h index aa654d6..b0933f2 100644 --- a/src/cmc/heap.h +++ b/src/cmc_heap.h @@ -1,5 +1,5 @@ /** - * cmc/heap.h + * cmc_heap.h * * Creation Date: 25/03/2019 * @@ -33,12 +33,12 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /* ------------------------------------------------------------------------- * Heap Implementation * ------------------------------------------------------------------------- */ -#include "../cor/heap.h" +#include "cor_heap.h" /** * Core Heap implementation diff --git a/src/cmc/intervalheap.h b/src/cmc_intervalheap.h similarity index 99% rename from src/cmc/intervalheap.h rename to src/cmc_intervalheap.h index 4094108..19db17c 100644 --- a/src/cmc/intervalheap.h +++ b/src/cmc_intervalheap.h @@ -1,5 +1,5 @@ /** - * cmc/intervalheap.h + * cmc_intervalheap.h * * Creation Date: 06/07/2019 * @@ -24,7 +24,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core IntervalHeap implementation diff --git a/src/cmc/linkedlist.h b/src/cmc_linkedlist.h similarity index 99% rename from src/cmc/linkedlist.h rename to src/cmc_linkedlist.h index 88479a0..13187ce 100644 --- a/src/cmc/linkedlist.h +++ b/src/cmc_linkedlist.h @@ -1,5 +1,5 @@ /** - * cmc/linkedlist.h + * cmc_linkedlist.h * * Creation Date: 22/03/2019 * @@ -31,7 +31,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core LinkedList implementation diff --git a/src/cmc/list.h b/src/cmc_list.h similarity index 99% rename from src/cmc/list.h rename to src/cmc_list.h index c98fe87..3a9ce07 100644 --- a/src/cmc/list.h +++ b/src/cmc_list.h @@ -1,5 +1,5 @@ /** - * cmc/list.h + * cmc_list.h * * Creation Date: 12/02/2019 * @@ -46,7 +46,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core List implementation diff --git a/src/cmc/queue.h b/src/cmc_queue.h similarity index 99% rename from src/cmc/queue.h rename to src/cmc_queue.h index acb73c3..a63f28b 100644 --- a/src/cmc/queue.h +++ b/src/cmc_queue.h @@ -1,5 +1,5 @@ /** - * cmc/queue.h + * cmc_queue.h * * Creation Date: 15/02/2019 * @@ -46,7 +46,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core Queue implementation diff --git a/src/cmc/sortedlist.h b/src/cmc_sortedlist.h similarity index 99% rename from src/cmc/sortedlist.h rename to src/cmc_sortedlist.h index 5f36f32..5bdede8 100644 --- a/src/cmc/sortedlist.h +++ b/src/cmc_sortedlist.h @@ -1,5 +1,5 @@ /** - * cmc/sortedlist.h + * cmc_sortedlist.h * * Creation Date: 17/09/2019 * @@ -25,7 +25,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core SortedList implementation diff --git a/src/cmc/stack.h b/src/cmc_stack.h similarity index 99% rename from src/cmc/stack.h rename to src/cmc_stack.h index cb60b1e..d56dc8f 100644 --- a/src/cmc/stack.h +++ b/src/cmc_stack.h @@ -1,5 +1,5 @@ /** - * cmc/stack.h + * cmc_stack.h * * Creation Date: 14/02/2019 * @@ -31,7 +31,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core Stack implementation diff --git a/src/cmc/treemap.h b/src/cmc_treemap.h similarity index 99% rename from src/cmc/treemap.h rename to src/cmc_treemap.h index bdc0fa6..8d23669 100644 --- a/src/cmc/treemap.h +++ b/src/cmc_treemap.h @@ -1,5 +1,5 @@ /** - * cmc/treemap.h + * cmc_treemap.h * * Creation Date: 28/03/2019 * @@ -22,7 +22,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core TreeMap implementation @@ -763,7 +763,7 @@ root = root->left; \ } \ \ - /* TODO this can be optimized by doing two in-order traversals */\ + /* TODO this can be optimized by doing two in-order traversals */ \ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map2_, root->key); \ \ if (node == NULL) \ diff --git a/src/cmc/treeset.h b/src/cmc_treeset.h similarity index 99% rename from src/cmc/treeset.h rename to src/cmc_treeset.h index be3ffd4..c80b393 100644 --- a/src/cmc/treeset.h +++ b/src/cmc_treeset.h @@ -1,5 +1,5 @@ /** - * cmc/treeset.h + * cmc_treeset.h * * Creation Date: 27/03/2019 * @@ -22,7 +22,7 @@ /* ------------------------------------------------------------------------- * Core functionalities of the C Macro Collections Library * ------------------------------------------------------------------------- */ -#include "../cor/core.h" +#include "cor_core.h" /** * Core TreeSet implementation diff --git a/src/cor/alloc.h b/src/cor_alloc.h similarity index 98% rename from src/cor/alloc.h rename to src/cor_alloc.h index 5d3edea..22dac63 100644 --- a/src/cor/alloc.h +++ b/src/cor_alloc.h @@ -1,5 +1,5 @@ /** - * cor/alloc.h + * cor_alloc.h * * Creation Date: 24/05/2020 * diff --git a/src/cor/bitset.h b/src/cor_bitset.h similarity index 96% rename from src/cor/bitset.h rename to src/cor_bitset.h index 9f793af..bbfa94f 100644 --- a/src/cor/bitset.h +++ b/src/cor_bitset.h @@ -1,5 +1,5 @@ /** - * cor/bitset.h + * cor_bitset.h * * Creation Date: 20/05/2020 * @@ -26,7 +26,7 @@ typedef CMC_BITSET_WORD_TYPE cmc_bitset_word; /** - * cmc_bit_to_index + * cmc_bidx_to_widx * * Translates a bit index to a word index */ diff --git a/src/cor/callbacks.h b/src/cor_callbacks.h similarity index 98% rename from src/cor/callbacks.h rename to src/cor_callbacks.h index 0ec86a6..1601c77 100644 --- a/src/cor/callbacks.h +++ b/src/cor_callbacks.h @@ -1,5 +1,5 @@ /** - * cor/callbacks.h + * cor_callbacks.h * * Creation Date: 24/05/2020 * diff --git a/src/cor/core.h b/src/cor_core.h similarity index 95% rename from src/cor/core.h rename to src/cor_core.h index 430d35d..f0d275e 100644 --- a/src/cor/core.h +++ b/src/cor_core.h @@ -1,5 +1,5 @@ /** - * cor/core.h + * cor_core.h * * Creation Date: 17/03/2020 * @@ -35,10 +35,10 @@ #include #include -#include "alloc.h" -#include "callbacks.h" -#include "flags.h" -#include "ftable.h" +#include "cor_alloc.h" +#include "cor_callbacks.h" +#include "cor_flags.h" +#include "cor_ftable.h" #define CMC__(A, B) A##B #define CMC_(A, B) CMC__(A, B) diff --git a/src/cor/flags.h b/src/cor_flags.h similarity index 97% rename from src/cor/flags.h rename to src/cor_flags.h index a9b0407..d8fd3d2 100644 --- a/src/cor/flags.h +++ b/src/cor_flags.h @@ -1,5 +1,5 @@ /** - * cor/flags.h + * cor_flags.h * * Creation Date: 14/05/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_COR_FLAGS_H #define CMC_COR_FLAGS_H -#include "core.h" +#include "cor_core.h" /** * enum cmc_flags diff --git a/src/cor/ftable.h b/src/cor_ftable.h similarity index 97% rename from src/cor/ftable.h rename to src/cor_ftable.h index cdeede6..21f38a3 100644 --- a/src/cor/ftable.h +++ b/src/cor_ftable.h @@ -1,5 +1,5 @@ /** - * cor/ftable.h + * cor_ftable.h * * Creation Date: 27/05/2020 * diff --git a/src/cor/hashtable.h b/src/cor_hashtable.h similarity index 97% rename from src/cor/hashtable.h rename to src/cor_hashtable.h index 08409db..a1b9c2c 100644 --- a/src/cor/hashtable.h +++ b/src/cor_hashtable.h @@ -1,5 +1,5 @@ /** - * cor/hashtable.h + * cor_hashtable.h * * Creation Date: 17/03/2020 * @@ -15,7 +15,7 @@ #ifndef CMC_COR_HASHTABLE_H #define CMC_COR_HASHTABLE_H -#include "core.h" +#include "cor_core.h" /** * CMC_ENTRY_DELETED diff --git a/src/cor/heap.h b/src/cor_heap.h similarity index 97% rename from src/cor/heap.h rename to src/cor_heap.h index 923e4e0..d2fe693 100644 --- a/src/cor/heap.h +++ b/src/cor_heap.h @@ -1,5 +1,5 @@ /** - * cor/heap.h + * cor_heap.h * * Creation Date: 01/06/2020 * diff --git a/src/ext/cmc/bitset.h b/src/ext_cmc_bitset.h similarity index 92% rename from src/ext/cmc/bitset.h rename to src/ext_cmc_bitset.h index 791abcc..4c713ff 100644 --- a/src/ext/cmc/bitset.h +++ b/src/ext_cmc_bitset.h @@ -1,5 +1,5 @@ /** - * ext/cmc/bitset.h + * ext_cmc_bitset.h * * Creation Date: 08/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_BITSET_H #define CMC_EXT_CMC_BITSET_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC BitSet. diff --git a/src/ext/cmc/deque.h b/src/ext_cmc_deque.h similarity index 99% rename from src/ext/cmc/deque.h rename to src/ext_cmc_deque.h index fb19ec6..622f359 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext_cmc_deque.h @@ -1,5 +1,5 @@ /** - * ext/cmc/deque.h + * ext_cmc_deque.h * * Creation Date: 25/05/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_DEQUE_H #define CMC_EXT_CMC_DEQUE_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC Deque. diff --git a/src/ext/cmc/hashbidimap.h b/src/ext_cmc_hashbidimap.h similarity index 98% rename from src/ext/cmc/hashbidimap.h rename to src/ext_cmc_hashbidimap.h index bf1e423..9eda3fb 100644 --- a/src/ext/cmc/hashbidimap.h +++ b/src/ext_cmc_hashbidimap.h @@ -1,5 +1,5 @@ /** - * ext/cmc/hashbidimap.h + * ext_cmc_hashbidimap.h * * Creation Date: 26/05/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_HASHBIDIMAP_H #define CMC_EXT_CMC_HASHBIDIMAP_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC HashBidiMap. diff --git a/src/ext/cmc/hashmap.h b/src/ext_cmc_hashmap.h similarity index 99% rename from src/ext/cmc/hashmap.h rename to src/ext_cmc_hashmap.h index 89a87de..151c267 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext_cmc_hashmap.h @@ -1,5 +1,5 @@ /** - * ext/cmc/hashmap.h + * ext_cmc_hashmap.h * * Creation Date: 25/05/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_HASHMAP_H #define CMC_EXT_CMC_HASHMAP_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC HashMap. diff --git a/src/ext/cmc/hashmultimap.h b/src/ext_cmc_hashmultimap.h similarity index 99% rename from src/ext/cmc/hashmultimap.h rename to src/ext_cmc_hashmultimap.h index ac03bd6..8e14619 100644 --- a/src/ext/cmc/hashmultimap.h +++ b/src/ext_cmc_hashmultimap.h @@ -1,5 +1,5 @@ /** - * ext/cmc/hashmultimap.h + * ext_cmc_hashmultimap.h * * Creation Date: 29/05/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_HASHMULTIMAP_H #define CMC_EXT_CMC_HASHMULTIMAP_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC HashMultiMap. diff --git a/src/ext/cmc/hashmultiset.h b/src/ext_cmc_hashmultiset.h similarity index 99% rename from src/ext/cmc/hashmultiset.h rename to src/ext_cmc_hashmultiset.h index 2aba7c8..36e0f18 100644 --- a/src/ext/cmc/hashmultiset.h +++ b/src/ext_cmc_hashmultiset.h @@ -1,5 +1,5 @@ /** - * ext/cmc/hashmultiset.h + * ext_cmc_hashmultiset.h * * Creation Date: 30/05/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_HASHMULTISET_H #define CMC_EXT_CMC_HASHMULTISET_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC HashMultiSet. diff --git a/src/ext/cmc/hashset.h b/src/ext_cmc_hashset.h similarity index 99% rename from src/ext/cmc/hashset.h rename to src/ext_cmc_hashset.h index ac42cba..d33eb39 100644 --- a/src/ext/cmc/hashset.h +++ b/src/ext_cmc_hashset.h @@ -1,5 +1,5 @@ /** - * ext/cmc/hashset.h + * ext_cmc_hashset.h * * Creation Date: 29/05/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_HASHSET_H #define CMC_EXT_CMC_HASHSET_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC HashSet. diff --git a/src/ext/cmc/heap.h b/src/ext_cmc_heap.h similarity index 99% rename from src/ext/cmc/heap.h rename to src/ext_cmc_heap.h index fa62ad0..822920d 100644 --- a/src/ext/cmc/heap.h +++ b/src/ext_cmc_heap.h @@ -1,5 +1,5 @@ /** - * ext/cmc/heap.h + * ext_cmc_heap.h * * Creation Date: 01/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_HEAP_H #define CMC_EXT_CMC_HEAP_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC Heap. diff --git a/src/ext/cmc/intervalheap.h b/src/ext_cmc_intervalheap.h similarity index 99% rename from src/ext/cmc/intervalheap.h rename to src/ext_cmc_intervalheap.h index d1f8ccf..fb37b99 100644 --- a/src/ext/cmc/intervalheap.h +++ b/src/ext_cmc_intervalheap.h @@ -1,5 +1,5 @@ /** - * ext/cmc/intervalheap.h + * ext_cmc_intervalheap.h * * Creation Date: 02/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_INTERVALHEAP_H #define CMC_EXT_CMC_INTERVALHEAP_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC IntervalHeap. diff --git a/src/ext/cmc/linkedlist.h b/src/ext_cmc_linkedlist.h similarity index 99% rename from src/ext/cmc/linkedlist.h rename to src/ext_cmc_linkedlist.h index 0e8982c..a531128 100644 --- a/src/ext/cmc/linkedlist.h +++ b/src/ext_cmc_linkedlist.h @@ -1,5 +1,5 @@ /** - * ext/cmc/linkedlist.h + * ext_cmc_linkedlist.h * * Creation Date: 03/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_LINKEDLIST_H #define CMC_EXT_CMC_LINKEDLIST_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC LinkedList. diff --git a/src/ext/cmc/list.h b/src/ext_cmc_list.h similarity index 99% rename from src/ext/cmc/list.h rename to src/ext_cmc_list.h index ad971c8..269adfd 100644 --- a/src/ext/cmc/list.h +++ b/src/ext_cmc_list.h @@ -1,5 +1,5 @@ /** - * ext/cmc/list.h + * ext_cmc_list.h * * Creation Date: 04/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_LIST_H #define CMC_EXT_CMC_LIST_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC List. diff --git a/src/ext/cmc/queue.h b/src/ext_cmc_queue.h similarity index 99% rename from src/ext/cmc/queue.h rename to src/ext_cmc_queue.h index 23a0e53..378e54c 100644 --- a/src/ext/cmc/queue.h +++ b/src/ext_cmc_queue.h @@ -1,5 +1,5 @@ /** - * ext/cmc/queue.h + * ext_cmc_queue.h * * Creation Date: 05/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_QUEUE_H #define CMC_EXT_CMC_QUEUE_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC Queue. diff --git a/src/ext/cmc/sortedlist.h b/src/ext_cmc_sortedlist.h similarity index 99% rename from src/ext/cmc/sortedlist.h rename to src/ext_cmc_sortedlist.h index fdfe0e4..8cd7487 100644 --- a/src/ext/cmc/sortedlist.h +++ b/src/ext_cmc_sortedlist.h @@ -1,5 +1,5 @@ /** - * ext/cmc/sortedlist.h + * ext_cmc_sortedlist.h * * Creation Date: 06/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_SORTEDLIST_H #define CMC_EXT_CMC_SORTEDLIST_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC SortedList. diff --git a/src/ext/cmc/stack.h b/src/ext_cmc_stack.h similarity index 99% rename from src/ext/cmc/stack.h rename to src/ext_cmc_stack.h index 0efdefd..4bba905 100644 --- a/src/ext/cmc/stack.h +++ b/src/ext_cmc_stack.h @@ -1,5 +1,5 @@ /** - * ext/cmc/stack.h + * ext_cmc_stack.h * * Creation Date: 07/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_STACK_H #define CMC_EXT_CMC_STACK_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC Stack. diff --git a/src/ext/cmc/treemap.h b/src/ext_cmc_treemap.h similarity index 99% rename from src/ext/cmc/treemap.h rename to src/ext_cmc_treemap.h index cf45ad0..f78fbdb 100644 --- a/src/ext/cmc/treemap.h +++ b/src/ext_cmc_treemap.h @@ -1,5 +1,5 @@ /** - * ext/cmc/treemap.h + * ext_cmc_treemap.h * * Creation Date: 08/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_TREEMAP_H #define CMC_EXT_CMC_TREEMAP_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC TreeMap. diff --git a/src/ext/cmc/treeset.h b/src/ext_cmc_treeset.h similarity index 99% rename from src/ext/cmc/treeset.h rename to src/ext_cmc_treeset.h index 9cc5ce5..5fffde9 100644 --- a/src/ext/cmc/treeset.h +++ b/src/ext_cmc_treeset.h @@ -1,5 +1,5 @@ /** - * ext/cmc/treeset.h + * ext_cmc_treeset.h * * Creation Date: 08/06/2020 * @@ -11,7 +11,7 @@ #ifndef CMC_EXT_CMC_TREESET_H #define CMC_EXT_CMC_TREESET_H -#include "../../cor/core.h" +#include "cor_core.h" /** * All the EXT parts of CMC TreeSet. diff --git a/src/macro_collections.h b/src/macro_collections.h index b6d91c4..73c4654 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -27,57 +27,57 @@ #define CMC_MACRO_COLLECTIONS_H // clang-format off -#include "cmc/bitset.h" /* Added in 30/04/2020 */ -#include "cmc/deque.h" /* Added in 20/03/2019 */ -#include "cmc/hashbidimap.h" /* Added in 26/09/2019 */ -#include "cmc/hashmap.h" /* Added in 03/04/2019 */ -#include "cmc/hashmultimap.h" /* Added in 26/04/2019 */ -#include "cmc/hashmultiset.h" /* Added in 10/04/2019 */ -#include "cmc/hashset.h" /* Added in 01/04/2019 */ -#include "cmc/heap.h" /* Added in 25/03/2019 */ -#include "cmc/intervalheap.h" /* Added in 06/07/2019 */ -#include "cmc/linkedlist.h" /* Added in 22/03/2019 */ -#include "cmc/list.h" /* Added in 12/02/2019 */ -#include "cmc/queue.h" /* Added in 15/02/2019 */ -#include "cmc/sortedlist.h" /* Added in 17/09/2019 */ -#include "cmc/stack.h" /* Added in 14/02/2019 */ -#include "cmc/treemap.h" /* Added in 28/03/2019 */ -#include "cmc/treeset.h" /* Added in 27/03/2019 */ +#include "cmc_bitset.h" /* Added in 30/04/2020 */ +#include "cmc_deque.h" /* Added in 20/03/2019 */ +#include "cmc_hashbidimap.h" /* Added in 26/09/2019 */ +#include "cmc_hashmap.h" /* Added in 03/04/2019 */ +#include "cmc_hashmultimap.h" /* Added in 26/04/2019 */ +#include "cmc_hashmultiset.h" /* Added in 10/04/2019 */ +#include "cmc_hashset.h" /* Added in 01/04/2019 */ +#include "cmc_heap.h" /* Added in 25/03/2019 */ +#include "cmc_intervalheap.h" /* Added in 06/07/2019 */ +#include "cmc_linkedlist.h" /* Added in 22/03/2019 */ +#include "cmc_list.h" /* Added in 12/02/2019 */ +#include "cmc_queue.h" /* Added in 15/02/2019 */ +#include "cmc_sortedlist.h" /* Added in 17/09/2019 */ +#include "cmc_stack.h" /* Added in 14/02/2019 */ +#include "cmc_treemap.h" /* Added in 28/03/2019 */ +#include "cmc_treeset.h" /* Added in 27/03/2019 */ -#include "cor/alloc.h" /* Added in 24/05/2020 */ -#include "cor/bitset.h" /* Added in 20/05/2020 */ -#include "cor/callbacks.h" /* Added in 24/05/2020 */ -#include "cor/core.h" /* Added in 17/03/2020 */ -#include "cor/flags.h" /* Added in 14/05/2020 */ -#include "cor/ftable.h" /* Added in 27/05/2020 */ -#include "cor/hashtable.h" /* Added in 17/03/2020 */ -#include "cor/heap.h" /* Added in 01/06/2020 */ +#include "cor_alloc.h" /* Added in 24/05/2020 */ +#include "cor_bitset.h" /* Added in 20/05/2020 */ +#include "cor_callbacks.h" /* Added in 24/05/2020 */ +#include "cor_core.h" /* Added in 17/03/2020 */ +#include "cor_flags.h" /* Added in 14/05/2020 */ +#include "cor_ftable.h" /* Added in 27/05/2020 */ +#include "cor_hashtable.h" /* Added in 17/03/2020 */ +#include "cor_heap.h" /* Added in 01/06/2020 */ -#include "ext/cmc/bitset.h" /* Added in 08/06/2020 */ -#include "ext/cmc/deque.h" /* Added in 25/05/2020 */ -#include "ext/cmc/hashbidimap.h" /* Added in 26/05/2020 */ -#include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */ -#include "ext/cmc/hashmultimap.h" /* Added in 29/05/2020 */ -#include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */ -#include "ext/cmc/hashset.h" /* Added in 31/05/2020 */ -#include "ext/cmc/heap.h" /* Added in 01/06/2020 */ -#include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */ -#include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */ -#include "ext/cmc/list.h" /* Added in 04/06/2020 */ -#include "ext/cmc/queue.h" /* Added in 05/06/2020 */ -#include "ext/cmc/sortedlist.h" /* Added in 06/06/2020 */ -#include "ext/cmc/stack.h" /* Added in 07/06/2020 */ -#include "ext/cmc/treemap.h" /* Added in 08/06/2020 */ -#include "ext/cmc/treeset.h" /* Added in 08/06/2020 */ +#include "ext_cmc_bitset.h" /* Added in 08/06/2020 */ +#include "ext_cmc_deque.h" /* Added in 25/05/2020 */ +#include "ext_cmc_hashbidimap.h" /* Added in 26/05/2020 */ +#include "ext_cmc_hashmap.h" /* Added in 25/05/2020 */ +#include "ext_cmc_hashmultimap.h" /* Added in 29/05/2020 */ +#include "ext_cmc_hashmultiset.h" /* Added in 30/05/2020 */ +#include "ext_cmc_hashset.h" /* Added in 31/05/2020 */ +#include "ext_cmc_heap.h" /* Added in 01/06/2020 */ +#include "ext_cmc_intervalheap.h" /* Added in 02/06/2020 */ +#include "ext_cmc_linkedlist.h" /* Added in 03/06/2020 */ +#include "ext_cmc_list.h" /* Added in 04/06/2020 */ +#include "ext_cmc_queue.h" /* Added in 05/06/2020 */ +#include "ext_cmc_sortedlist.h" /* Added in 06/06/2020 */ +#include "ext_cmc_stack.h" /* Added in 07/06/2020 */ +#include "ext_cmc_treemap.h" /* Added in 08/06/2020 */ +#include "ext_cmc_treeset.h" /* Added in 08/06/2020 */ -#include "utl/assert.h" /* Added in 27/06/2019 */ -#include "utl/foreach.h" /* Added in 25/02/2019 */ -#include "utl/futils.h" /* Added in 15/04/2020 */ -#include "utl/log.h" /* Added in 21/06/2019 */ -#include "utl/mutex.h" /* Added in 14/05/2020 */ -#include "utl/test.h" /* Added in 26/06/2019 */ -#include "utl/thread.h" /* Added in 14/05/2020 */ -#include "utl/timer.h" /* Added in 12/04/2019 */ +#include "utl_assert.h" /* Added in 27/06/2019 */ +#include "utl_foreach.h" /* Added in 25/02/2019 */ +#include "utl_futils.h" /* Added in 15/04/2020 */ +#include "utl_log.h" /* Added in 21/06/2019 */ +#include "utl_mutex.h" /* Added in 14/05/2020 */ +#include "utl_test.h" /* Added in 26/06/2019 */ +#include "utl_thread.h" /* Added in 14/05/2020 */ +#include "utl_timer.h" /* Added in 12/04/2019 */ // clang-format on /** diff --git a/src/utl/assert.h b/src/utl_assert.h similarity index 99% rename from src/utl/assert.h rename to src/utl_assert.h index 110acb6..1ca4d56 100644 --- a/src/utl/assert.h +++ b/src/utl_assert.h @@ -1,5 +1,5 @@ /** - * utl/assert.h + * utl_assert.h * * Creation Date: 27/06/2019 * @@ -56,7 +56,7 @@ #include #include -#include "../cor/core.h" +#include "cor_core.h" #define CMC_ASSERT_GLUE_(dtype, assertion) cmc_assert_##assertion##_##dtype #define CMC_ASSERT_GLUE(dtype, assertion) CMC_ASSERT_GLUE_(dtype, assertion) diff --git a/src/utl/foreach.h b/src/utl_foreach.h similarity index 95% rename from src/utl/foreach.h rename to src/utl_foreach.h index d625380..de0b2f4 100644 --- a/src/utl/foreach.h +++ b/src/utl_foreach.h @@ -1,5 +1,5 @@ /** - * utl/foreach.h + * utl_foreach.h * * Creation Date: 25/02/2019 * @@ -20,7 +20,7 @@ #ifndef CMC_UTL_FOREACH_H #define CMC_UTL_FOREACH_H -#include "../cor/core.h" +#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); \ diff --git a/src/utl/futils.h b/src/utl_futils.h similarity index 99% rename from src/utl/futils.h rename to src/utl_futils.h index 26726dc..8128148 100644 --- a/src/utl/futils.h +++ b/src/utl_futils.h @@ -1,5 +1,5 @@ /** - * utl/futils.h + * utl_futils.h * * Creation Date: 15/04/2020 * diff --git a/src/utl/log.h b/src/utl_log.h similarity index 99% rename from src/utl/log.h rename to src/utl_log.h index 284f429..6100638 100644 --- a/src/utl/log.h +++ b/src/utl_log.h @@ -1,5 +1,5 @@ /** - * utl/log.h + * utl_log.h * * Creation Date: 21/06/2019 * @@ -64,7 +64,7 @@ #include #include -#include "../cor/core.h" +#include "cor_core.h" static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" }; diff --git a/src/utl/mutex.h b/src/utl_mutex.h similarity index 99% rename from src/utl/mutex.h rename to src/utl_mutex.h index 69678e6..2d57d50 100644 --- a/src/utl/mutex.h +++ b/src/utl_mutex.h @@ -1,5 +1,5 @@ /** - * utl/mutex.h + * utl_mutex.h * * Creation Date: 14/05/2020 * @@ -27,7 +27,7 @@ #include -#include "../cor/flags.h" +#include "cor_flags.h" #if defined(_WIN32) #define CMC_MUTEX_WINDOWS diff --git a/src/utl/test.h b/src/utl_test.h similarity index 98% rename from src/utl/test.h rename to src/utl_test.h index 07238c2..75efd08 100644 --- a/src/utl/test.h +++ b/src/utl_test.h @@ -1,5 +1,5 @@ /** - * utl/test.h + * utl_test.h * * Creation Date: 26/06/2019 * @@ -42,9 +42,9 @@ #include #include -#include "../cor/core.h" -#include "assert.h" -#include "timer.h" +#include "cor_core.h" +#include "utl_assert.h" +#include "utl_timer.h" struct cmc_test_info { diff --git a/src/utl/thread.h b/src/utl_thread.h similarity index 98% rename from src/utl/thread.h rename to src/utl_thread.h index 22c34e5..dfc9da0 100644 --- a/src/utl/thread.h +++ b/src/utl_thread.h @@ -1,5 +1,5 @@ /** - * utl/thread.h + * utl_thread.h * * Creation Date: 14/05/2020 * @@ -26,7 +26,7 @@ #include #include -#include "../cor/flags.h" +#include "cor_flags.h" #if defined(_WIN32) #define CMC_THREAD_WINDOWS diff --git a/src/utl/timer.h b/src/utl_timer.h similarity index 98% rename from src/utl/timer.h rename to src/utl_timer.h index 79857c3..8f75e97 100644 --- a/src/utl/timer.h +++ b/src/utl_timer.h @@ -1,5 +1,5 @@ /** - * utl/timer.h + * utl_timer.h * * Creation Date: 12/04/2019 * diff --git a/tests/codecov.c b/tests/codecov.c index 442ba00..fd16011 100644 --- a/tests/codecov.c +++ b/tests/codecov.c @@ -5,63 +5,63 @@ #include "macro_collections.h" -#include "cmc/bitset.h" -#include "cmc/deque.h" -#include "cmc/hashbidimap.h" -#include "cmc/hashmap.h" -#include "cmc/hashmultimap.h" -#include "cmc/hashmultiset.h" -#include "cmc/hashset.h" -#include "cmc/heap.h" -#include "cmc/intervalheap.h" -#include "cmc/linkedlist.h" -#include "cmc/list.h" -#include "cmc/queue.h" -#include "cmc/sortedlist.h" -#include "cmc/stack.h" -#include "cmc/treemap.h" -#include "cmc/treeset.h" +#include "tst_cmc_bitset.h" +#include "tst_cmc_deque.h" +#include "tst_cmc_hashbidimap.h" +#include "tst_cmc_hashmap.h" +#include "tst_cmc_hashmultimap.h" +#include "tst_cmc_hashmultiset.h" +#include "tst_cmc_hashset.h" +#include "tst_cmc_heap.h" +#include "tst_cmc_intervalheap.h" +#include "tst_cmc_linkedlist.h" +#include "tst_cmc_list.h" +#include "tst_cmc_queue.h" +#include "tst_cmc_sortedlist.h" +#include "tst_cmc_stack.h" +#include "tst_cmc_treemap.h" +#include "tst_cmc_treeset.h" -#include "cmc/bitset.c" -#include "cmc/deque.c" -#include "cmc/hashbidimap.c" -#include "cmc/hashmap.c" -#include "cmc/hashmultimap.c" -#include "cmc/hashmultiset.c" -#include "cmc/hashset.c" -#include "cmc/heap.c" -#include "cmc/intervalheap.c" -#include "cmc/linkedlist.c" -#include "cmc/list.c" -#include "cmc/queue.c" -#include "cmc/sortedlist.c" -#include "cmc/stack.c" -#include "cmc/treemap.c" -#include "cmc/treeset.c" +#include "tst_cmc_bitset.c" +#include "tst_cmc_deque.c" +#include "tst_cmc_hashbidimap.c" +#include "tst_cmc_hashmap.c" +#include "tst_cmc_hashmultimap.c" +#include "tst_cmc_hashmultiset.c" +#include "tst_cmc_hashset.c" +#include "tst_cmc_heap.c" +#include "tst_cmc_intervalheap.c" +#include "tst_cmc_linkedlist.c" +#include "tst_cmc_list.c" +#include "tst_cmc_queue.c" +#include "tst_cmc_sortedlist.c" +#include "tst_cmc_stack.c" +#include "tst_cmc_treemap.c" +#include "tst_cmc_treeset.c" -#include "unt/cmc/bitset.h" -#include "unt/cmc/deque.h" -#include "unt/cmc/hashbidimap.h" -#include "unt/cmc/hashmap.h" -#include "unt/cmc/hashmultimap.h" -#include "unt/cmc/hashmultiset.h" -#include "unt/cmc/hashset.h" -#include "unt/cmc/heap.h" -#include "unt/cmc/intervalheap.h" -#include "unt/cmc/linkedlist.h" -#include "unt/cmc/list.h" -#include "unt/cmc/queue.h" -#include "unt/cmc/sortedlist.h" -#include "unt/cmc/stack.h" -#include "unt/cmc/treemap.h" -#include "unt/cmc/treeset.h" +#include "unt_cmc_bitset.h" +#include "unt_cmc_deque.h" +#include "unt_cmc_hashbidimap.h" +#include "unt_cmc_hashmap.h" +#include "unt_cmc_hashmultimap.h" +#include "unt_cmc_hashmultiset.h" +#include "unt_cmc_hashset.h" +#include "unt_cmc_heap.h" +#include "unt_cmc_intervalheap.h" +#include "unt_cmc_linkedlist.h" +#include "unt_cmc_list.h" +#include "unt_cmc_queue.h" +#include "unt_cmc_sortedlist.h" +#include "unt_cmc_stack.h" +#include "unt_cmc_treemap.h" +#include "unt_cmc_treeset.h" -#include "unt/utl/foreach.h" +#include "unt_utl_foreach.h" -#include "utl/assert.h" -#include "utl/timer.h" +#include "utl_assert.h" +#include "utl_timer.h" -#include "./unt/utl.h" +#include "utl.h" #define cmc_run(unit, unit_fails, test_fails) \ do \ diff --git a/tests/include/cmc/bitset.h b/tests/include/cmc/bitset.h deleted file mode 100644 index 0c693e0..0000000 --- a/tests/include/cmc/bitset.h +++ /dev/null @@ -1,44 +0,0 @@ - -#ifndef CMC_CMC_BITSET_TEST_H -#define CMC_CMC_BITSET_TEST_H - -#include "macro_collections.h" - -struct bitset -{ - cmc_bitset_word *buffer; - size_t capacity; - size_t count; - int flag; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct bitset_iter -{ - struct bitset *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct bitset *bs_new(size_t n_bits); -struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -struct bitset bs_init(size_t n_bits); -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void bs_free(struct bitset *_bitset_); -void bs_release(struct bitset _bitset_); -void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool bs_set(struct bitset *_bitset_, size_t bit_index); -_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_clear(struct bitset *_bitset_, size_t bit_index); -_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_flip(struct bitset *_bitset_, size_t bit_index); -_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state); -_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state); -_Bool bs_set_all(struct bitset *_bitset_); -_Bool bs_clear_all(struct bitset *_bitset_); -_Bool bs_flip_all(struct bitset *_bitset_); -_Bool bs_get(struct bitset *_bitset_, size_t bit_index); -_Bool bs_resize(struct bitset *_bitset_, size_t n_bits); - -#endif /* CMC_CMC_BITSET_TEST_H */ diff --git a/tests/include/cmc/deque.h b/tests/include/cmc/deque.h deleted file mode 100644 index b664e2a..0000000 --- a/tests/include/cmc/deque.h +++ /dev/null @@ -1,78 +0,0 @@ - -#ifndef CMC_CMC_DEQUE_TEST_H -#define CMC_CMC_DEQUE_TEST_H - -#include "macro_collections.h" - -struct deque -{ - size_t *buffer; - size_t capacity; - size_t count; - size_t front; - size_t back; - int flag; - struct deque_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct deque_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct deque *d_new(size_t capacity, struct deque_fval *f_val); -struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void d_clear(struct deque *_deque_); -void d_free(struct deque *_deque_); -void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool d_push_front(struct deque *_deque_, size_t value); -_Bool d_push_back(struct deque *_deque_, size_t value); -_Bool d_pop_front(struct deque *_deque_); -_Bool d_pop_back(struct deque *_deque_); -size_t d_front(struct deque *_deque_); -size_t d_back(struct deque *_deque_); -_Bool d_contains(struct deque *_deque_, size_t value); -_Bool d_empty(struct deque *_deque_); -_Bool d_full(struct deque *_deque_); -size_t d_count(struct deque *_deque_); -size_t d_capacity(struct deque *_deque_); -int d_flag(struct deque *_deque_); -_Bool d_resize(struct deque *_deque_, size_t capacity); -struct deque *d_copy_of(struct deque *_deque_); -_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_); -struct deque d_init(size_t capacity, struct deque_fval *f_val); -struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void d_release(struct deque _deque_); -struct deque_iter -{ - struct deque *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct deque_iter d_iter_start(struct deque *target); -struct deque_iter d_iter_end(struct deque *target); -_Bool d_iter_at_start(struct deque_iter *iter); -_Bool d_iter_at_end(struct deque_iter *iter); -_Bool d_iter_to_start(struct deque_iter *iter); -_Bool d_iter_to_end(struct deque_iter *iter); -_Bool d_iter_next(struct deque_iter *iter); -_Bool d_iter_prev(struct deque_iter *iter); -_Bool d_iter_advance(struct deque_iter *iter, size_t steps); -_Bool d_iter_rewind(struct deque_iter *iter, size_t steps); -_Bool d_iter_go_to(struct deque_iter *iter, size_t index); -size_t d_iter_value(struct deque_iter *iter); -size_t *d_iter_rvalue(struct deque_iter *iter); -size_t d_iter_index(struct deque_iter *iter); -_Bool d_to_string(struct deque *_deque_, FILE *fptr); -_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_DEQUE_TEST_H */ diff --git a/tests/include/cmc/hashbidimap.h b/tests/include/cmc/hashbidimap.h deleted file mode 100644 index c574437..0000000 --- a/tests/include/cmc/hashbidimap.h +++ /dev/null @@ -1,101 +0,0 @@ - -#ifndef CMC_CMC_HASHBIDIMAP_TEST_H -#define CMC_CMC_HASHBIDIMAP_TEST_H - -#include "macro_collections.h" - -struct hashbidimap -{ - struct hashbidimap_entry *(*buffer)[2]; - size_t capacity; - size_t count; - double load; - int flag; - struct hashbidimap_fkey *f_key; - struct hashbidimap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; - struct hashbidimap_iter (*it_start)(struct hashbidimap *); - struct hashbidimap_iter (*it_end)(struct hashbidimap *); -}; -struct hashbidimap_entry -{ - size_t key; - size_t value; - size_t dist[2]; - struct hashbidimap_entry **ref[2]; -}; -struct hashbidimap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashbidimap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashbidimap_iter -{ - struct hashbidimap *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val); -struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hbm_clear(struct hashbidimap *_map_); -void hbm_free(struct hashbidimap *_map_); -void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value); -_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key); -_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val); -_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val); -_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val); -size_t hbm_get_key(struct hashbidimap *_map_, size_t val); -size_t hbm_get_val(struct hashbidimap *_map_, size_t key); -_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key); -_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val); -_Bool hbm_empty(struct hashbidimap *_map_); -_Bool hbm_full(struct hashbidimap *_map_); -size_t hbm_count(struct hashbidimap *_map_); -size_t hbm_capacity(struct hashbidimap *_map_); -double hbm_load(struct hashbidimap *_map_); -int hbm_flag(struct hashbidimap *_map_); -_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity); -struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_); -_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_); -struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target); -void hbm_iter_free(struct hashbidimap_iter *iter); -void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target); -_Bool hbm_iter_start(struct hashbidimap_iter *iter); -_Bool hbm_iter_end(struct hashbidimap_iter *iter); -void hbm_iter_to_start(struct hashbidimap_iter *iter); -void hbm_iter_to_end(struct hashbidimap_iter *iter); -_Bool hbm_iter_next(struct hashbidimap_iter *iter); -_Bool hbm_iter_prev(struct hashbidimap_iter *iter); -_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps); -_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps); -_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); -size_t hbm_iter_key(struct hashbidimap_iter *iter); -size_t hbm_iter_value(struct hashbidimap_iter *iter); -size_t hbm_iter_index(struct hashbidimap_iter *iter); -_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr); -_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_HASHBIDIMAP_TEST_H */ diff --git a/tests/include/cmc/hashmap.h b/tests/include/cmc/hashmap.h deleted file mode 100644 index 5bb61eb..0000000 --- a/tests/include/cmc/hashmap.h +++ /dev/null @@ -1,100 +0,0 @@ - -#ifndef CMC_CMC_HASHMAP_TEST_H -#define CMC_CMC_HASHMAP_TEST_H - -#include "macro_collections.h" - -struct hashmap -{ - struct hashmap_entry *buffer; - size_t capacity; - size_t count; - double load; - int flag; - struct hashmap_fkey *f_key; - struct hashmap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmap_entry -{ - size_t key; - size_t value; - size_t dist; - enum cmc_entry_state state; -}; -struct hashmap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); -struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hm_clear(struct hashmap *_map_); -void hm_free(struct hashmap *_map_); -void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); -_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value); -_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value); -_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value); -_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value); -size_t hm_get(struct hashmap *_map_, size_t key); -size_t *hm_get_ref(struct hashmap *_map_, size_t key); -_Bool hm_contains(struct hashmap *_map_, size_t key); -_Bool hm_empty(struct hashmap *_map_); -_Bool hm_full(struct hashmap *_map_); -size_t hm_count(struct hashmap *_map_); -size_t hm_capacity(struct hashmap *_map_); -double hm_load(struct hashmap *_map_); -int hm_flag(struct hashmap *_map_); -_Bool hm_resize(struct hashmap *_map_, size_t capacity); -struct hashmap *hm_copy_of(struct hashmap *_map_); -_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_); -struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); -struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hm_release(struct hashmap _map_); -struct hashmap_iter -{ - struct hashmap *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmap_iter hm_iter_start(struct hashmap *target); -struct hashmap_iter hm_iter_end(struct hashmap *target); -_Bool hm_iter_at_start(struct hashmap_iter *iter); -_Bool hm_iter_at_end(struct hashmap_iter *iter); -_Bool hm_iter_to_start(struct hashmap_iter *iter); -_Bool hm_iter_to_end(struct hashmap_iter *iter); -_Bool hm_iter_next(struct hashmap_iter *iter); -_Bool hm_iter_prev(struct hashmap_iter *iter); -_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps); -_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps); -_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index); -size_t hm_iter_key(struct hashmap_iter *iter); -size_t hm_iter_value(struct hashmap_iter *iter); -size_t *hm_iter_rvalue(struct hashmap_iter *iter); -size_t hm_iter_index(struct hashmap_iter *iter); -_Bool hm_to_string(struct hashmap *_map_, FILE *fptr); -_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_HASHMAP_TEST_H */ diff --git a/tests/include/cmc/hashmultimap.h b/tests/include/cmc/hashmultimap.h deleted file mode 100644 index 7b44266..0000000 --- a/tests/include/cmc/hashmultimap.h +++ /dev/null @@ -1,102 +0,0 @@ - -#ifndef CMC_CMC_HASHMULTIMAP_TEST_H -#define CMC_CMC_HASHMULTIMAP_TEST_H - -#include "macro_collections.h" - -struct hashmultimap -{ - struct hashmultimap_entry *(*buffer)[2]; - size_t capacity; - size_t count; - double load; - int flag; - struct hashmultimap_fkey *f_key; - struct hashmultimap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmultimap_entry -{ - size_t key; - size_t value; - struct hashmultimap_entry *next; - struct hashmultimap_entry *prev; -}; -struct hashmultimap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultimap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val); -struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hmm_clear(struct hashmultimap *_map_); -void hmm_free(struct hashmultimap *_map_); -void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value); -_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value); -size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values); -_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value); -size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values); -_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value); -_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value); -size_t hmm_get(struct hashmultimap *_map_, size_t key); -size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key); -_Bool hmm_contains(struct hashmultimap *_map_, size_t key); -_Bool hmm_empty(struct hashmultimap *_map_); -_Bool hmm_full(struct hashmultimap *_map_); -size_t hmm_count(struct hashmultimap *_map_); -size_t hmm_key_count(struct hashmultimap *_map_, size_t key); -size_t hmm_capacity(struct hashmultimap *_map_); -double hmm_load(struct hashmultimap *_map_); -int hmm_flag(struct hashmultimap *_map_); -_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity); -struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_); -_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_); -struct hashmultimap_iter -{ - struct hashmultimap *target; - struct hashmultimap_entry *curr_entry; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target); -struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target); -_Bool hmm_iter_at_start(struct hashmultimap_iter *iter); -_Bool hmm_iter_at_end(struct hashmultimap_iter *iter); -_Bool hmm_iter_to_start(struct hashmultimap_iter *iter); -_Bool hmm_iter_to_end(struct hashmultimap_iter *iter); -_Bool hmm_iter_next(struct hashmultimap_iter *iter); -_Bool hmm_iter_prev(struct hashmultimap_iter *iter); -_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps); -_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps); -_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index); -size_t hmm_iter_key(struct hashmultimap_iter *iter); -size_t hmm_iter_value(struct hashmultimap_iter *iter); -size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter); -size_t hmm_iter_index(struct hashmultimap_iter *iter); -_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr); -_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_HASHMULTIMAP_TEST_H */ diff --git a/tests/include/cmc/hashmultiset.h b/tests/include/cmc/hashmultiset.h deleted file mode 100644 index 6ab4627..0000000 --- a/tests/include/cmc/hashmultiset.h +++ /dev/null @@ -1,98 +0,0 @@ - -#ifndef CMC_CMC_HASHMULTISET_TEST_H -#define CMC_CMC_HASHMULTISET_TEST_H - -#include "macro_collections.h" - -struct hashmultiset -{ - struct hashmultiset_entry *buffer; - size_t capacity; - size_t count; - size_t cardinality; - double load; - int flag; - struct hashmultiset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmultiset_entry -{ - size_t value; - size_t multiplicity; - size_t dist; - enum cmc_entry_state state; -}; -struct hashmultiset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val); -struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hms_clear(struct hashmultiset *_set_); -void hms_free(struct hashmultiset *_set_); -void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hms_insert(struct hashmultiset *_set_, size_t value); -_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count); -_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity); -_Bool hms_remove(struct hashmultiset *_set_, size_t value); -size_t hms_remove_all(struct hashmultiset *_set_, size_t value); -_Bool hms_max(struct hashmultiset *_set_, size_t *value); -_Bool hms_min(struct hashmultiset *_set_, size_t *value); -size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value); -_Bool hms_contains(struct hashmultiset *_set_, size_t value); -_Bool hms_empty(struct hashmultiset *_set_); -_Bool hms_full(struct hashmultiset *_set_); -size_t hms_count(struct hashmultiset *_set_); -size_t hms_cardinality(struct hashmultiset *_set_); -size_t hms_capacity(struct hashmultiset *_set_); -double hms_load(struct hashmultiset *_set_); -int hms_flag(struct hashmultiset *_set_); -_Bool hms_resize(struct hashmultiset *_set_, size_t capacity); -struct hashmultiset *hms_copy_of(struct hashmultiset *_set_); -_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset_iter -{ - struct hashmultiset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmultiset_iter hms_iter_start(struct hashmultiset *target); -struct hashmultiset_iter hms_iter_end(struct hashmultiset *target); -_Bool hms_iter_at_start(struct hashmultiset_iter *iter); -_Bool hms_iter_at_end(struct hashmultiset_iter *iter); -_Bool hms_iter_to_start(struct hashmultiset_iter *iter); -_Bool hms_iter_to_end(struct hashmultiset_iter *iter); -_Bool hms_iter_next(struct hashmultiset_iter *iter); -_Bool hms_iter_prev(struct hashmultiset_iter *iter); -_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps); -_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps); -_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index); -size_t hms_iter_value(struct hashmultiset_iter *iter); -size_t hms_iter_multiplicity(struct hashmultiset_iter *iter); -size_t hms_iter_index(struct hashmultiset_iter *iter); -struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr); -_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_HASHMULTISET_TEST_H */ diff --git a/tests/include/cmc/hashset.h b/tests/include/cmc/hashset.h deleted file mode 100644 index a9ab75c..0000000 --- a/tests/include/cmc/hashset.h +++ /dev/null @@ -1,88 +0,0 @@ - -#ifndef CMC_CMC_HASHSET_TEST_H -#define CMC_CMC_HASHSET_TEST_H - -#include "macro_collections.h" - -struct hashset -{ - struct hashset_entry *buffer; - size_t capacity; - size_t count; - double load; - int flag; - struct hashset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashset_entry -{ - size_t value; - size_t dist; - enum cmc_entry_state state; -}; -struct hashset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val); -struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hs_clear(struct hashset *_set_); -void hs_free(struct hashset *_set_); -void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hs_insert(struct hashset *_set_, size_t value); -_Bool hs_remove(struct hashset *_set_, size_t value); -_Bool hs_max(struct hashset *_set_, size_t *value); -_Bool hs_min(struct hashset *_set_, size_t *value); -_Bool hs_contains(struct hashset *_set_, size_t value); -_Bool hs_empty(struct hashset *_set_); -_Bool hs_full(struct hashset *_set_); -size_t hs_count(struct hashset *_set_); -size_t hs_capacity(struct hashset *_set_); -double hs_load(struct hashset *_set_); -int hs_flag(struct hashset *_set_); -_Bool hs_resize(struct hashset *_set_, size_t capacity); -struct hashset *hs_copy_of(struct hashset *_set_); -_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_); -struct hashset_iter -{ - struct hashset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashset_iter hs_iter_start(struct hashset *target); -struct hashset_iter hs_iter_end(struct hashset *target); -_Bool hs_iter_at_start(struct hashset_iter *iter); -_Bool hs_iter_at_end(struct hashset_iter *iter); -_Bool hs_iter_to_start(struct hashset_iter *iter); -_Bool hs_iter_to_end(struct hashset_iter *iter); -_Bool hs_iter_next(struct hashset_iter *iter); -_Bool hs_iter_prev(struct hashset_iter *iter); -_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps); -_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps); -_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index); -size_t hs_iter_value(struct hashset_iter *iter); -size_t hs_iter_index(struct hashset_iter *iter); -struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_to_string(struct hashset *_set_, FILE *fptr); -_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_HASHSET_TEST_H */ diff --git a/tests/include/cmc/heap.h b/tests/include/cmc/heap.h deleted file mode 100644 index 8b062f1..0000000 --- a/tests/include/cmc/heap.h +++ /dev/null @@ -1,68 +0,0 @@ - -#ifndef CMC_CMC_HEAP_TEST_H -#define CMC_CMC_HEAP_TEST_H - -#include "macro_collections.h" - -struct heap -{ - size_t *buffer; - size_t capacity; - size_t count; - enum cmc_heap_order HO; - int flag; - struct heap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct heap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val); -struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void h_clear(struct heap *_heap_); -void h_free(struct heap *_heap_); -void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool h_insert(struct heap *_heap_, size_t value); -_Bool h_remove(struct heap *_heap_); -size_t h_peek(struct heap *_heap_); -_Bool h_contains(struct heap *_heap_, size_t value); -_Bool h_empty(struct heap *_heap_); -_Bool h_full(struct heap *_heap_); -size_t h_count(struct heap *_heap_); -size_t h_capacity(struct heap *_heap_); -int h_flag(struct heap *_heap_); -_Bool h_resize(struct heap *_heap_, size_t capacity); -struct heap *h_copy_of(struct heap *_heap_); -_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_); -struct heap_iter -{ - struct heap *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct heap_iter h_iter_start(struct heap *target); -struct heap_iter h_iter_end(struct heap *target); -_Bool h_iter_at_start(struct heap_iter *iter); -_Bool h_iter_at_end(struct heap_iter *iter); -_Bool h_iter_to_start(struct heap_iter *iter); -_Bool h_iter_to_end(struct heap_iter *iter); -_Bool h_iter_next(struct heap_iter *iter); -_Bool h_iter_prev(struct heap_iter *iter); -_Bool h_iter_advance(struct heap_iter *iter, size_t steps); -_Bool h_iter_rewind(struct heap_iter *iter, size_t steps); -_Bool h_iter_go_to(struct heap_iter *iter, size_t index); -size_t h_iter_value(struct heap_iter *iter); -size_t h_iter_index(struct heap_iter *iter); -_Bool h_to_string(struct heap *_heap_, FILE *fptr); -_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_HEAP_TEST_H */ diff --git a/tests/include/cmc/intervalheap.h b/tests/include/cmc/intervalheap.h deleted file mode 100644 index 5bc4fb2..0000000 --- a/tests/include/cmc/intervalheap.h +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef CMC_CMC_INTERVALHEAP_TEST_H -#define CMC_CMC_INTERVALHEAP_TEST_H - -#include "macro_collections.h" - -struct intervalheap -{ - size_t (*buffer)[2]; - size_t capacity; - size_t size; - size_t count; - int flag; - struct intervalheap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct intervalheap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val); -struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ih_clear(struct intervalheap *_heap_); -void ih_free(struct intervalheap *_heap_); -void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ih_insert(struct intervalheap *_heap_, size_t value); -_Bool ih_remove_max(struct intervalheap *_heap_); -_Bool ih_remove_min(struct intervalheap *_heap_); -_Bool ih_update_max(struct intervalheap *_heap_, size_t value); -_Bool ih_update_min(struct intervalheap *_heap_, size_t value); -size_t ih_max(struct intervalheap *_heap_); -size_t ih_min(struct intervalheap *_heap_); -_Bool ih_contains(struct intervalheap *_heap_, size_t value); -_Bool ih_empty(struct intervalheap *_heap_); -_Bool ih_full(struct intervalheap *_heap_); -size_t ih_count(struct intervalheap *_heap_); -size_t ih_capacity(struct intervalheap *_heap_); -int ih_flag(struct intervalheap *_heap_); -_Bool ih_resize(struct intervalheap *_heap_, size_t capacity); -struct intervalheap *ih_copy_of(struct intervalheap *_heap_); -_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_); -struct intervalheap_iter -{ - struct intervalheap *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct intervalheap_iter ih_iter_start(struct intervalheap *target); -struct intervalheap_iter ih_iter_end(struct intervalheap *target); -_Bool ih_iter_at_start(struct intervalheap_iter *iter); -_Bool ih_iter_at_end(struct intervalheap_iter *iter); -_Bool ih_iter_to_start(struct intervalheap_iter *iter); -_Bool ih_iter_to_end(struct intervalheap_iter *iter); -_Bool ih_iter_next(struct intervalheap_iter *iter); -_Bool ih_iter_prev(struct intervalheap_iter *iter); -_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps); -_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps); -_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index); -size_t ih_iter_value(struct intervalheap_iter *iter); -size_t ih_iter_index(struct intervalheap_iter *iter); -_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr); -_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_INTERVALHEAP_TEST_H */ diff --git a/tests/include/cmc/linkedlist.h b/tests/include/cmc/linkedlist.h deleted file mode 100644 index c06925d..0000000 --- a/tests/include/cmc/linkedlist.h +++ /dev/null @@ -1,92 +0,0 @@ - -#ifndef CMC_CMC_LINKEDLIST_TEST_H -#define CMC_CMC_LINKEDLIST_TEST_H - -#include "macro_collections.h" - -struct linkedlist -{ - struct linkedlist_node *head; - struct linkedlist_node *tail; - size_t count; - int flag; - struct linkedlist_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct linkedlist_node -{ - size_t value; - struct linkedlist_node *next; - struct linkedlist_node *prev; -}; -struct linkedlist_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct linkedlist *ll_new(struct linkedlist_fval *f_val); -struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ll_clear(struct linkedlist *_list_); -void ll_free(struct linkedlist *_list_); -void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ll_push_front(struct linkedlist *_list_, size_t value); -_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index); -_Bool ll_push_back(struct linkedlist *_list_, size_t value); -_Bool ll_pop_front(struct linkedlist *_list_); -_Bool ll_pop_at(struct linkedlist *_list_, size_t index); -_Bool ll_pop_back(struct linkedlist *_list_); -size_t ll_front(struct linkedlist *_list_); -size_t ll_get(struct linkedlist *_list_, size_t index); -size_t *ll_get_ref(struct linkedlist *_list_, size_t index); -size_t ll_back(struct linkedlist *_list_); -_Bool ll_contains(struct linkedlist *_list_, size_t value); -_Bool ll_empty(struct linkedlist *_list_); -size_t ll_count(struct linkedlist *_list_); -int ll_flag(struct linkedlist *_list_); -struct linkedlist *ll_copy_of(struct linkedlist *_list_); -_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_); -struct linkedlist_iter -{ - struct linkedlist *target; - struct linkedlist_node *cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct linkedlist_iter ll_iter_start(struct linkedlist *target); -struct linkedlist_iter ll_iter_end(struct linkedlist *target); -_Bool ll_iter_at_start(struct linkedlist_iter *iter); -_Bool ll_iter_at_end(struct linkedlist_iter *iter); -_Bool ll_iter_to_start(struct linkedlist_iter *iter); -_Bool ll_iter_to_end(struct linkedlist_iter *iter); -_Bool ll_iter_next(struct linkedlist_iter *iter); -_Bool ll_iter_prev(struct linkedlist_iter *iter); -_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps); -_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps); -_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index); -size_t ll_iter_value(struct linkedlist_iter *iter); -size_t *ll_iter_rvalue(struct linkedlist_iter *iter); -size_t ll_iter_index(struct linkedlist_iter *iter); -struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter); -struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); -void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_head(struct linkedlist *_list_); -struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); -struct linkedlist_node *ll_tail(struct linkedlist *_list_); -_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); -struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); -_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr); -_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_LINKEDLIST_TEST_H */ diff --git a/tests/include/cmc/list.h b/tests/include/cmc/list.h deleted file mode 100644 index 3a1043d..0000000 --- a/tests/include/cmc/list.h +++ /dev/null @@ -1,82 +0,0 @@ - -#ifndef CMC_CMC_LIST_TEST_H -#define CMC_CMC_LIST_TEST_H - -#include "macro_collections.h" - -struct list -{ - size_t *buffer; - size_t capacity; - size_t count; - int flag; - struct list_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct list_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct list *l_new(size_t capacity, struct list_fval *f_val); -struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void l_clear(struct list *_list_); -void l_free(struct list *_list_); -void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool l_push_front(struct list *_list_, size_t value); -_Bool l_push_at(struct list *_list_, size_t value, size_t index); -_Bool l_push_back(struct list *_list_, size_t value); -_Bool l_pop_front(struct list *_list_); -_Bool l_pop_at(struct list *_list_, size_t index); -_Bool l_pop_back(struct list *_list_); -size_t l_front(struct list *_list_); -size_t l_get(struct list *_list_, size_t index); -size_t *l_get_ref(struct list *_list_, size_t index); -size_t l_back(struct list *_list_); -size_t l_index_of(struct list *_list_, size_t value, _Bool from_start); -_Bool l_contains(struct list *_list_, size_t value); -_Bool l_empty(struct list *_list_); -_Bool l_full(struct list *_list_); -size_t l_count(struct list *_list_); -_Bool l_fits(struct list *_list_, size_t size); -size_t l_capacity(struct list *_list_); -int l_flag(struct list *_list_); -_Bool l_resize(struct list *_list_, size_t capacity); -struct list *l_copy_of(struct list *_list_); -_Bool l_equals(struct list *_list1_, struct list *_list2_); -struct list_iter -{ - struct list *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct list_iter l_iter_start(struct list *target); -struct list_iter l_iter_end(struct list *target); -_Bool l_iter_at_start(struct list_iter *iter); -_Bool l_iter_at_end(struct list_iter *iter); -_Bool l_iter_to_start(struct list_iter *iter); -_Bool l_iter_to_end(struct list_iter *iter); -_Bool l_iter_next(struct list_iter *iter); -_Bool l_iter_prev(struct list_iter *iter); -_Bool l_iter_advance(struct list_iter *iter, size_t steps); -_Bool l_iter_rewind(struct list_iter *iter, size_t steps); -_Bool l_iter_go_to(struct list_iter *iter, size_t index); -size_t l_iter_value(struct list_iter *iter); -size_t *l_iter_rvalue(struct list_iter *iter); -size_t l_iter_index(struct list_iter *iter); -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); -_Bool l_to_string(struct list *_list_, FILE *fptr); -_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_LIST_TEST_H */ diff --git a/tests/include/cmc/queue.h b/tests/include/cmc/queue.h deleted file mode 100644 index 1fcd7b1..0000000 --- a/tests/include/cmc/queue.h +++ /dev/null @@ -1,71 +0,0 @@ - -#ifndef CMC_CMC_QUEUE_TEST_H -#define CMC_CMC_QUEUE_TEST_H - -#include "macro_collections.h" - -struct queue -{ - size_t *buffer; - size_t capacity; - size_t count; - size_t front; - size_t back; - int flag; - struct queue_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct queue_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct queue *q_new(size_t capacity, struct queue_fval *f_val); -struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void q_clear(struct queue *_queue_); -void q_free(struct queue *_queue_); -void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool q_enqueue(struct queue *_queue_, size_t value); -_Bool q_dequeue(struct queue *_queue_); -size_t q_peek(struct queue *_queue_); -_Bool q_contains(struct queue *_queue_, size_t value); -_Bool q_empty(struct queue *_queue_); -_Bool q_full(struct queue *_queue_); -size_t q_count(struct queue *_queue_); -size_t q_capacity(struct queue *_queue_); -int q_flag(struct queue *_queue_); -_Bool q_resize(struct queue *_queue_, size_t capacity); -struct queue *q_copy_of(struct queue *_queue_); -_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_); -struct queue_iter -{ - struct queue *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct queue_iter q_iter_start(struct queue *target); -struct queue_iter q_iter_end(struct queue *target); -_Bool q_iter_at_start(struct queue_iter *iter); -_Bool q_iter_at_end(struct queue_iter *iter); -_Bool q_iter_to_start(struct queue_iter *iter); -_Bool q_iter_to_end(struct queue_iter *iter); -_Bool q_iter_next(struct queue_iter *iter); -_Bool q_iter_prev(struct queue_iter *iter); -_Bool q_iter_advance(struct queue_iter *iter, size_t steps); -_Bool q_iter_rewind(struct queue_iter *iter, size_t steps); -_Bool q_iter_go_to(struct queue_iter *iter, size_t index); -size_t q_iter_value(struct queue_iter *iter); -size_t *q_iter_rvalue(struct queue_iter *iter); -size_t q_iter_index(struct queue_iter *iter); -_Bool q_to_string(struct queue *_queue_, FILE *fptr); -_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_QUEUE_TEST_H */ diff --git a/tests/include/cmc/sortedlist.h b/tests/include/cmc/sortedlist.h deleted file mode 100644 index a34b155..0000000 --- a/tests/include/cmc/sortedlist.h +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef CMC_CMC_SORTEDLIST_TEST_H -#define CMC_CMC_SORTEDLIST_TEST_H - -#include "macro_collections.h" - -struct sortedlist -{ - size_t *buffer; - size_t capacity; - size_t count; - _Bool is_sorted; - int flag; - struct sortedlist_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct sortedlist_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val); -struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void sl_clear(struct sortedlist *_list_); -void sl_free(struct sortedlist *_list_); -void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool sl_insert(struct sortedlist *_list_, size_t value); -_Bool sl_remove(struct sortedlist *_list_, size_t index); -size_t sl_max(struct sortedlist *_list_); -size_t sl_min(struct sortedlist *_list_); -size_t sl_get(struct sortedlist *_list_, size_t index); -size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start); -_Bool sl_contains(struct sortedlist *_list_, size_t value); -_Bool sl_empty(struct sortedlist *_list_); -_Bool sl_full(struct sortedlist *_list_); -size_t sl_count(struct sortedlist *_list_); -size_t sl_capacity(struct sortedlist *_list_); -int sl_flag(struct sortedlist *_list_); -_Bool sl_resize(struct sortedlist *_list_, size_t capacity); -void sl_sort(struct sortedlist *_list_); -struct sortedlist *sl_copy_of(struct sortedlist *_list_); -_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_); -struct sortedlist_iter -{ - struct sortedlist *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct sortedlist_iter sl_iter_start(struct sortedlist *target); -struct sortedlist_iter sl_iter_end(struct sortedlist *target); -_Bool sl_iter_at_start(struct sortedlist_iter *iter); -_Bool sl_iter_at_end(struct sortedlist_iter *iter); -_Bool sl_iter_to_start(struct sortedlist_iter *iter); -_Bool sl_iter_to_end(struct sortedlist_iter *iter); -_Bool sl_iter_next(struct sortedlist_iter *iter); -_Bool sl_iter_prev(struct sortedlist_iter *iter); -_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps); -_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps); -_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index); -size_t sl_iter_value(struct sortedlist_iter *iter); -size_t sl_iter_index(struct sortedlist_iter *iter); -_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr); -_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_SORTEDLIST_TEST_H */ diff --git a/tests/include/cmc/stack.h b/tests/include/cmc/stack.h deleted file mode 100644 index 6f510d0..0000000 --- a/tests/include/cmc/stack.h +++ /dev/null @@ -1,68 +0,0 @@ - -#ifndef CMC_CMC_STACK_TEST_H -#define CMC_CMC_STACK_TEST_H - -#include "macro_collections.h" - -struct stack -{ - size_t *buffer; - size_t capacity; - size_t count; - int flag; - struct stack_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct stack_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct stack *s_new(size_t capacity, struct stack_fval *f_val); -struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void s_clear(struct stack *_stack_); -void s_free(struct stack *_stack_); -void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool s_push(struct stack *_stack_, size_t value); -_Bool s_pop(struct stack *_stack_); -size_t s_top(struct stack *_stack_); -_Bool s_contains(struct stack *_stack_, size_t value); -_Bool s_empty(struct stack *_stack_); -_Bool s_full(struct stack *_stack_); -size_t s_count(struct stack *_stack_); -size_t s_capacity(struct stack *_stack_); -int s_flag(struct stack *_stack_); -_Bool s_resize(struct stack *_stack_, size_t capacity); -struct stack *s_copy_of(struct stack *_stack_); -_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_); -struct stack_iter -{ - struct stack *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct stack_iter s_iter_start(struct stack *target); -struct stack_iter s_iter_end(struct stack *target); -_Bool s_iter_at_start(struct stack_iter *iter); -_Bool s_iter_at_end(struct stack_iter *iter); -_Bool s_iter_to_start(struct stack_iter *iter); -_Bool s_iter_to_end(struct stack_iter *iter); -_Bool s_iter_next(struct stack_iter *iter); -_Bool s_iter_prev(struct stack_iter *iter); -_Bool s_iter_advance(struct stack_iter *iter, size_t steps); -_Bool s_iter_rewind(struct stack_iter *iter, size_t steps); -_Bool s_iter_go_to(struct stack_iter *iter, size_t index); -size_t s_iter_value(struct stack_iter *iter); -size_t *s_iter_rvalue(struct stack_iter *iter); -size_t s_iter_index(struct stack_iter *iter); -_Bool s_to_string(struct stack *_stack_, FILE *fptr); -_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_STACK_TEST_H */ diff --git a/tests/include/cmc/treemap.h b/tests/include/cmc/treemap.h deleted file mode 100644 index 005ad91..0000000 --- a/tests/include/cmc/treemap.h +++ /dev/null @@ -1,92 +0,0 @@ - -#ifndef CMC_CMC_TREEMAP_TEST_H -#define CMC_CMC_TREEMAP_TEST_H - -#include "macro_collections.h" - -struct treemap -{ - struct treemap_node *root; - size_t count; - int flag; - struct treemap_fkey *f_key; - struct treemap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct treemap_node -{ - size_t key; - size_t value; - unsigned char height; - struct treemap_node *right; - struct treemap_node *left; - struct treemap_node *parent; -}; -struct treemap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treemap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val); -struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void tm_clear(struct treemap *_map_); -void tm_free(struct treemap *_map_); -void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool tm_insert(struct treemap *_map_, size_t key, size_t value); -_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value); -_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value); -_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value); -_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value); -size_t tm_get(struct treemap *_map_, size_t key); -size_t *tm_get_ref(struct treemap *_map_, size_t key); -_Bool tm_contains(struct treemap *_map_, size_t key); -_Bool tm_empty(struct treemap *_map_); -size_t tm_count(struct treemap *_map_); -int tm_flag(struct treemap *_map_); -struct treemap *tm_copy_of(struct treemap *_map_); -_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_); -struct treemap_iter -{ - struct treemap *target; - struct treemap_node *cursor; - struct treemap_node *first; - struct treemap_node *last; - size_t index; - _Bool start; - _Bool end; -}; -struct treemap_iter tm_iter_start(struct treemap *target); -struct treemap_iter tm_iter_end(struct treemap *target); -_Bool tm_iter_at_start(struct treemap_iter *iter); -_Bool tm_iter_at_end(struct treemap_iter *iter); -_Bool tm_iter_to_start(struct treemap_iter *iter); -_Bool tm_iter_to_end(struct treemap_iter *iter); -_Bool tm_iter_next(struct treemap_iter *iter); -_Bool tm_iter_prev(struct treemap_iter *iter); -_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps); -_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps); -_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index); -size_t tm_iter_key(struct treemap_iter *iter); -size_t tm_iter_value(struct treemap_iter *iter); -size_t *tm_iter_rvalue(struct treemap_iter *iter); -size_t tm_iter_index(struct treemap_iter *iter); -_Bool tm_to_string(struct treemap *_map_, FILE *fptr); -_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_TREEMAP_TEST_H */ diff --git a/tests/include/cmc/treeset.h b/tests/include/cmc/treeset.h deleted file mode 100644 index 9bca697..0000000 --- a/tests/include/cmc/treeset.h +++ /dev/null @@ -1,84 +0,0 @@ - -#ifndef CMC_CMC_TREESET_TEST_H -#define CMC_CMC_TREESET_TEST_H - -#include "macro_collections.h" - -struct treeset -{ - struct treeset_node *root; - size_t count; - int flag; - struct treeset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct treeset_node -{ - size_t value; - unsigned char height; - struct treeset_node *right; - struct treeset_node *left; - struct treeset_node *parent; -}; -struct treeset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treeset *ts_new(struct treeset_fval *f_val); -struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ts_clear(struct treeset *_set_); -void ts_free(struct treeset *_set_); -void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ts_insert(struct treeset *_set_, size_t value); -_Bool ts_remove(struct treeset *_set_, size_t value); -_Bool ts_max(struct treeset *_set_, size_t *value); -_Bool ts_min(struct treeset *_set_, size_t *value); -_Bool ts_contains(struct treeset *_set_, size_t value); -_Bool ts_empty(struct treeset *_set_); -size_t ts_count(struct treeset *_set_); -int ts_flag(struct treeset *_set_); -struct treeset *ts_copy_of(struct treeset *_set_); -_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); -struct treeset_iter -{ - struct treeset *target; - struct treeset_node *cursor; - struct treeset_node *first; - struct treeset_node *last; - size_t index; - _Bool start; - _Bool end; -}; -struct treeset_iter ts_iter_start(struct treeset *target); -struct treeset_iter ts_iter_end(struct treeset *target); -_Bool ts_iter_at_start(struct treeset_iter *iter); -_Bool ts_iter_at_end(struct treeset_iter *iter); -_Bool ts_iter_to_start(struct treeset_iter *iter); -_Bool ts_iter_to_end(struct treeset_iter *iter); -_Bool ts_iter_next(struct treeset_iter *iter); -_Bool ts_iter_prev(struct treeset_iter *iter); -_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps); -_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); -_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); -size_t ts_iter_value(struct treeset_iter *iter); -size_t ts_iter_index(struct treeset_iter *iter); -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_to_string(struct treeset *_set_, FILE *fptr); -_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_TREESET_TEST_H */ diff --git a/tests/include/tst_cmc_bitset.h b/tests/include/tst_cmc_bitset.h new file mode 100644 index 0000000..9e1998c --- /dev/null +++ b/tests/include/tst_cmc_bitset.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_BITSET_TEST_H + #define CMC_CMC_BITSET_TEST_H + + #include "macro_collections.h" + + struct bitset { cmc_bitset_word *buffer; size_t capacity; size_t count; int flag; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct bitset_iter { struct bitset *target; size_t cursor; _Bool start; _Bool end; }; struct bitset *bs_new(size_t n_bits); struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); struct bitset bs_init(size_t n_bits); struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void bs_free(struct bitset * _bitset_); void bs_release(struct bitset _bitset_); void bs_customize(struct bitset * _bitset_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool bs_set(struct bitset * _bitset_, size_t bit_index); _Bool bs_set_range(struct bitset * _bitset_, size_t from, size_t to); _Bool bs_clear(struct bitset * _bitset_, size_t bit_index); _Bool bs_clear_range(struct bitset * _bitset_, size_t from, size_t to); _Bool bs_flip(struct bitset * _bitset_, size_t bit_index); _Bool bs_flip_range(struct bitset * _bitset_, size_t from, size_t to); _Bool bs_put(struct bitset * _bitset_, size_t bit_index, _Bool state); _Bool bs_put_range(struct bitset * _bitset_, size_t from, size_t to, _Bool state); _Bool bs_set_all(struct bitset * _bitset_); _Bool bs_clear_all(struct bitset * _bitset_); _Bool bs_flip_all(struct bitset * _bitset_); _Bool bs_get(struct bitset * _bitset_, size_t bit_index); _Bool bs_resize(struct bitset * _bitset_, size_t n_bits); + + + #endif /* CMC_CMC_BITSET_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_deque.h b/tests/include/tst_cmc_deque.h new file mode 100644 index 0000000..70e222f --- /dev/null +++ b/tests/include/tst_cmc_deque.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_DEQUE_TEST_H + #define CMC_CMC_DEQUE_TEST_H + + #include "macro_collections.h" + + struct deque { size_t *buffer; size_t capacity; size_t count; size_t front; size_t back; int flag; struct deque_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct deque_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct deque *d_new(size_t capacity, struct deque_fval * f_val); struct deque *d_new_custom(size_t capacity, struct deque_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void d_clear(struct deque * _deque_); void d_free(struct deque * _deque_); void d_customize(struct deque * _deque_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool d_push_front(struct deque * _deque_, size_t value); _Bool d_push_back(struct deque * _deque_, size_t value); _Bool d_pop_front(struct deque * _deque_); _Bool d_pop_back(struct deque * _deque_); size_t d_front(struct deque * _deque_); size_t d_back(struct deque * _deque_); _Bool d_contains(struct deque * _deque_, size_t value); _Bool d_empty(struct deque * _deque_); _Bool d_full(struct deque * _deque_); size_t d_count(struct deque * _deque_); size_t d_capacity(struct deque * _deque_); int d_flag(struct deque * _deque_); _Bool d_resize(struct deque * _deque_, size_t capacity); struct deque *d_copy_of(struct deque * _deque_); _Bool d_equals(struct deque * _deque1_, struct deque * _deque2_); struct deque d_init(size_t capacity, struct deque_fval * f_val); struct deque d_init_custom(size_t capacity, struct deque_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void d_release(struct deque _deque_); struct deque_iter { struct deque *target; size_t cursor; size_t index; _Bool start; _Bool end; }; struct deque_iter d_iter_start(struct deque * target); struct deque_iter d_iter_end(struct deque * target); _Bool d_iter_at_start(struct deque_iter * iter); _Bool d_iter_at_end(struct deque_iter * iter); _Bool d_iter_to_start(struct deque_iter * iter); _Bool d_iter_to_end(struct deque_iter * iter); _Bool d_iter_next(struct deque_iter * iter); _Bool d_iter_prev(struct deque_iter * iter); _Bool d_iter_advance(struct deque_iter * iter, size_t steps); _Bool d_iter_rewind(struct deque_iter * iter, size_t steps); _Bool d_iter_go_to(struct deque_iter * iter, size_t index); size_t d_iter_value(struct deque_iter * iter); size_t *d_iter_rvalue(struct deque_iter * iter); size_t d_iter_index(struct deque_iter * iter); _Bool d_to_string(struct deque * _deque_, FILE * fptr); _Bool d_print(struct deque * _deque_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_DEQUE_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_hashbidimap.h b/tests/include/tst_cmc_hashbidimap.h new file mode 100644 index 0000000..a9a6387 --- /dev/null +++ b/tests/include/tst_cmc_hashbidimap.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_HASHBIDIMAP_TEST_H + #define CMC_CMC_HASHBIDIMAP_TEST_H + + #include "macro_collections.h" + + struct hashbidimap { struct hashbidimap_entry * (*buffer)[2]; size_t capacity; size_t count; double load; int flag; struct hashbidimap_fkey * f_key; struct hashbidimap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; struct hashbidimap_iter (*it_start)(struct hashbidimap *); struct hashbidimap_iter (*it_end)(struct hashbidimap *); }; struct hashbidimap_entry { size_t key; size_t value; size_t dist[2]; struct hashbidimap_entry * *ref[2]; }; struct hashbidimap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashbidimap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashbidimap_iter { struct hashbidimap *target; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey * f_key, struct hashbidimap_fval * f_val); struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey * f_key, struct hashbidimap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hbm_clear(struct hashbidimap * _map_); void hbm_free(struct hashbidimap * _map_); void hbm_customize(struct hashbidimap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hbm_insert(struct hashbidimap * _map_, size_t key, size_t value); _Bool hbm_update_key(struct hashbidimap * _map_, size_t val, size_t new_key); _Bool hbm_update_val(struct hashbidimap * _map_, size_t key, size_t new_val); _Bool hbm_remove_by_key(struct hashbidimap * _map_, size_t key, size_t * out_key, size_t * out_val); _Bool hbm_remove_by_val(struct hashbidimap * _map_, size_t val, size_t * out_key, size_t * out_val); size_t hbm_get_key(struct hashbidimap * _map_, size_t val); size_t hbm_get_val(struct hashbidimap * _map_, size_t key); _Bool hbm_contains_key(struct hashbidimap * _map_, size_t key); _Bool hbm_contains_val(struct hashbidimap * _map_, size_t val); _Bool hbm_empty(struct hashbidimap * _map_); _Bool hbm_full(struct hashbidimap * _map_); size_t hbm_count(struct hashbidimap * _map_); size_t hbm_capacity(struct hashbidimap * _map_); double hbm_load(struct hashbidimap * _map_); int hbm_flag(struct hashbidimap * _map_); _Bool hbm_resize(struct hashbidimap * _map_, size_t capacity); struct hashbidimap *hbm_copy_of(struct hashbidimap * _map_); _Bool hbm_equals(struct hashbidimap * _map1_, struct hashbidimap * _map2_); struct hashbidimap_iter * hbm_iter_new(struct hashbidimap * target); void hbm_iter_free(struct hashbidimap_iter * iter); void hbm_iter_init(struct hashbidimap_iter * iter, struct hashbidimap * target); _Bool hbm_iter_start(struct hashbidimap_iter * iter); _Bool hbm_iter_end(struct hashbidimap_iter * iter); void hbm_iter_to_start(struct hashbidimap_iter * iter); void hbm_iter_to_end(struct hashbidimap_iter * iter); _Bool hbm_iter_next(struct hashbidimap_iter * iter); _Bool hbm_iter_prev(struct hashbidimap_iter * iter); _Bool hbm_iter_advance(struct hashbidimap_iter * iter, size_t steps); _Bool hbm_iter_rewind(struct hashbidimap_iter * iter, size_t steps); _Bool hbm_iter_go_to(struct hashbidimap_iter * iter, size_t index); size_t hbm_iter_key(struct hashbidimap_iter * iter); size_t hbm_iter_value(struct hashbidimap_iter * iter); size_t hbm_iter_index(struct hashbidimap_iter * iter); _Bool hbm_to_string(struct hashbidimap * _map_, FILE * fptr); _Bool hbm_print(struct hashbidimap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); + + + #endif /* CMC_CMC_HASHBIDIMAP_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_hashmap.h b/tests/include/tst_cmc_hashmap.h new file mode 100644 index 0000000..490bae1 --- /dev/null +++ b/tests/include/tst_cmc_hashmap.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_HASHMAP_TEST_H + #define CMC_CMC_HASHMAP_TEST_H + + #include "macro_collections.h" + + struct hashmap { struct hashmap_entry * buffer; size_t capacity; size_t count; double load; int flag; struct hashmap_fkey * f_key; struct hashmap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct hashmap_entry { size_t key; size_t value; size_t dist; enum cmc_entry_state state; }; struct hashmap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val); struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hm_clear(struct hashmap * _map_); void hm_free(struct hashmap * _map_); void hm_customize(struct hashmap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hm_insert(struct hashmap * _map_, size_t key, size_t value); _Bool hm_update(struct hashmap * _map_, size_t key, size_t new_value, size_t * old_value); _Bool hm_remove(struct hashmap * _map_, size_t key, size_t * out_value); _Bool hm_max(struct hashmap * _map_, size_t * key, size_t * value); _Bool hm_min(struct hashmap * _map_, size_t * key, size_t * value); size_t hm_get(struct hashmap * _map_, size_t key); size_t *hm_get_ref(struct hashmap * _map_, size_t key); _Bool hm_contains(struct hashmap * _map_, size_t key); _Bool hm_empty(struct hashmap * _map_); _Bool hm_full(struct hashmap * _map_); size_t hm_count(struct hashmap * _map_); size_t hm_capacity(struct hashmap * _map_); double hm_load(struct hashmap * _map_); int hm_flag(struct hashmap * _map_); _Bool hm_resize(struct hashmap * _map_, size_t capacity); struct hashmap *hm_copy_of(struct hashmap * _map_); _Bool hm_equals(struct hashmap * _map1_, struct hashmap * _map2_); struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val); struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hm_release(struct hashmap _map_); struct hashmap_iter { struct hashmap *target; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashmap_iter hm_iter_start(struct hashmap * target); struct hashmap_iter hm_iter_end(struct hashmap * target); _Bool hm_iter_at_start(struct hashmap_iter * iter); _Bool hm_iter_at_end(struct hashmap_iter * iter); _Bool hm_iter_to_start(struct hashmap_iter * iter); _Bool hm_iter_to_end(struct hashmap_iter * iter); _Bool hm_iter_next(struct hashmap_iter * iter); _Bool hm_iter_prev(struct hashmap_iter * iter); _Bool hm_iter_advance(struct hashmap_iter * iter, size_t steps); _Bool hm_iter_rewind(struct hashmap_iter * iter, size_t steps); _Bool hm_iter_go_to(struct hashmap_iter * iter, size_t index); size_t hm_iter_key(struct hashmap_iter * iter); size_t hm_iter_value(struct hashmap_iter * iter); size_t *hm_iter_rvalue(struct hashmap_iter * iter); size_t hm_iter_index(struct hashmap_iter * iter); _Bool hm_to_string(struct hashmap * _map_, FILE * fptr); _Bool hm_print(struct hashmap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); + + + #endif /* CMC_CMC_HASHMAP_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_hashmultimap.h b/tests/include/tst_cmc_hashmultimap.h new file mode 100644 index 0000000..883ad18 --- /dev/null +++ b/tests/include/tst_cmc_hashmultimap.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_HASHMULTIMAP_TEST_H + #define CMC_CMC_HASHMULTIMAP_TEST_H + + #include "macro_collections.h" + + struct hashmultimap { struct hashmultimap_entry * (*buffer)[2]; size_t capacity; size_t count; double load; int flag; struct hashmultimap_fkey * f_key; struct hashmultimap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct hashmultimap_entry { size_t key; size_t value; struct hashmultimap_entry * next; struct hashmultimap_entry * prev; }; struct hashmultimap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmultimap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey * f_key, struct hashmultimap_fval * f_val); struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey * f_key, struct hashmultimap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hmm_clear(struct hashmultimap * _map_); void hmm_free(struct hashmultimap * _map_); void hmm_customize(struct hashmultimap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hmm_insert(struct hashmultimap * _map_, size_t key, size_t value); _Bool hmm_update(struct hashmultimap * _map_, size_t key, size_t new_value, size_t * old_value); size_t hmm_update_all(struct hashmultimap * _map_, size_t key, size_t new_value, size_t * *old_values); _Bool hmm_remove(struct hashmultimap * _map_, size_t key, size_t * out_value); size_t hmm_remove_all(struct hashmultimap * _map_, size_t key, size_t * *out_values); _Bool hmm_max(struct hashmultimap * _map_, size_t * key, size_t * value); _Bool hmm_min(struct hashmultimap * _map_, size_t * key, size_t * value); size_t hmm_get(struct hashmultimap * _map_, size_t key); size_t *hmm_get_ref(struct hashmultimap * _map_, size_t key); _Bool hmm_contains(struct hashmultimap * _map_, size_t key); _Bool hmm_empty(struct hashmultimap * _map_); _Bool hmm_full(struct hashmultimap * _map_); size_t hmm_count(struct hashmultimap * _map_); size_t hmm_key_count(struct hashmultimap * _map_, size_t key); size_t hmm_capacity(struct hashmultimap * _map_); double hmm_load(struct hashmultimap * _map_); int hmm_flag(struct hashmultimap * _map_); _Bool hmm_resize(struct hashmultimap * _map_, size_t capacity); struct hashmultimap *hmm_copy_of(struct hashmultimap * _map_); _Bool hmm_equals(struct hashmultimap * _map1_, struct hashmultimap * _map2_); struct hashmultimap_iter { struct hashmultimap *target; struct hashmultimap_entry * curr_entry; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashmultimap_iter hmm_iter_start(struct hashmultimap * target); struct hashmultimap_iter hmm_iter_end(struct hashmultimap * target); _Bool hmm_iter_at_start(struct hashmultimap_iter * iter); _Bool hmm_iter_at_end(struct hashmultimap_iter * iter); _Bool hmm_iter_to_start(struct hashmultimap_iter * iter); _Bool hmm_iter_to_end(struct hashmultimap_iter * iter); _Bool hmm_iter_next(struct hashmultimap_iter * iter); _Bool hmm_iter_prev(struct hashmultimap_iter * iter); _Bool hmm_iter_advance(struct hashmultimap_iter * iter, size_t steps); _Bool hmm_iter_rewind(struct hashmultimap_iter * iter, size_t steps); _Bool hmm_iter_go_to(struct hashmultimap_iter * iter, size_t index); size_t hmm_iter_key(struct hashmultimap_iter * iter); size_t hmm_iter_value(struct hashmultimap_iter * iter); size_t *hmm_iter_rvalue(struct hashmultimap_iter * iter); size_t hmm_iter_index(struct hashmultimap_iter * iter); _Bool hmm_to_string(struct hashmultimap * _map_, FILE * fptr); _Bool hmm_print(struct hashmultimap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); + + + #endif /* CMC_CMC_HASHMULTIMAP_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_hashmultiset.h b/tests/include/tst_cmc_hashmultiset.h new file mode 100644 index 0000000..8fc3e80 --- /dev/null +++ b/tests/include/tst_cmc_hashmultiset.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_HASHMULTISET_TEST_H + #define CMC_CMC_HASHMULTISET_TEST_H + + #include "macro_collections.h" + + struct hashmultiset { struct hashmultiset_entry * buffer; size_t capacity; size_t count; size_t cardinality; double load; int flag; struct hashmultiset_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct hashmultiset_entry { size_t value; size_t multiplicity; size_t dist; enum cmc_entry_state state; }; struct hashmultiset_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval * f_val); struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hms_clear(struct hashmultiset * _set_); void hms_free(struct hashmultiset * _set_); void hms_customize(struct hashmultiset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hms_insert(struct hashmultiset * _set_, size_t value); _Bool hms_insert_many(struct hashmultiset * _set_, size_t value, size_t count); _Bool hms_update(struct hashmultiset * _set_, size_t value, size_t multiplicity); _Bool hms_remove(struct hashmultiset * _set_, size_t value); size_t hms_remove_all(struct hashmultiset * _set_, size_t value); _Bool hms_max(struct hashmultiset * _set_, size_t * value); _Bool hms_min(struct hashmultiset * _set_, size_t * value); size_t hms_multiplicity_of(struct hashmultiset * _set_, size_t value); _Bool hms_contains(struct hashmultiset * _set_, size_t value); _Bool hms_empty(struct hashmultiset * _set_); _Bool hms_full(struct hashmultiset * _set_); size_t hms_count(struct hashmultiset * _set_); size_t hms_cardinality(struct hashmultiset * _set_); size_t hms_capacity(struct hashmultiset * _set_); double hms_load(struct hashmultiset * _set_); int hms_flag(struct hashmultiset * _set_); _Bool hms_resize(struct hashmultiset * _set_, size_t capacity); struct hashmultiset *hms_copy_of(struct hashmultiset * _set_); _Bool hms_equals(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset_iter { struct hashmultiset *target; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashmultiset_iter hms_iter_start(struct hashmultiset * target); struct hashmultiset_iter hms_iter_end(struct hashmultiset * target); _Bool hms_iter_at_start(struct hashmultiset_iter * iter); _Bool hms_iter_at_end(struct hashmultiset_iter * iter); _Bool hms_iter_to_start(struct hashmultiset_iter * iter); _Bool hms_iter_to_end(struct hashmultiset_iter * iter); _Bool hms_iter_next(struct hashmultiset_iter * iter); _Bool hms_iter_prev(struct hashmultiset_iter * iter); _Bool hms_iter_advance(struct hashmultiset_iter * iter, size_t steps); _Bool hms_iter_rewind(struct hashmultiset_iter * iter, size_t steps); _Bool hms_iter_go_to(struct hashmultiset_iter * iter, size_t index); size_t hms_iter_value(struct hashmultiset_iter * iter); size_t hms_iter_multiplicity(struct hashmultiset_iter * iter); size_t hms_iter_index(struct hashmultiset_iter * iter); struct hashmultiset *hms_union(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset *hms_intersection(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset *hms_difference(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset *hms_summation(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset *hms_symmetric_difference(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_subset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_superset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_proper_subset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_proper_superset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_disjointset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_to_string(struct hashmultiset * _set_, FILE * fptr); _Bool hms_print(struct hashmultiset * _set_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); + + + #endif /* CMC_CMC_HASHMULTISET_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_hashset.h b/tests/include/tst_cmc_hashset.h new file mode 100644 index 0000000..bf1b031 --- /dev/null +++ b/tests/include/tst_cmc_hashset.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_HASHSET_TEST_H + #define CMC_CMC_HASHSET_TEST_H + + #include "macro_collections.h" + + struct hashset { struct hashset_entry * buffer; size_t capacity; size_t count; double load; int flag; struct hashset_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct hashset_entry { size_t value; size_t dist; enum cmc_entry_state state; }; struct hashset_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashset *hs_new(size_t capacity, double load, struct hashset_fval * f_val); struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hs_clear(struct hashset * _set_); void hs_free(struct hashset * _set_); void hs_customize(struct hashset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hs_insert(struct hashset * _set_, size_t value); _Bool hs_remove(struct hashset * _set_, size_t value); _Bool hs_max(struct hashset * _set_, size_t * value); _Bool hs_min(struct hashset * _set_, size_t * value); _Bool hs_contains(struct hashset * _set_, size_t value); _Bool hs_empty(struct hashset * _set_); _Bool hs_full(struct hashset * _set_); size_t hs_count(struct hashset * _set_); size_t hs_capacity(struct hashset * _set_); double hs_load(struct hashset * _set_); int hs_flag(struct hashset * _set_); _Bool hs_resize(struct hashset * _set_, size_t capacity); struct hashset *hs_copy_of(struct hashset * _set_); _Bool hs_equals(struct hashset * _set1_, struct hashset * _set2_); struct hashset_iter { struct hashset *target; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashset_iter hs_iter_start(struct hashset * target); struct hashset_iter hs_iter_end(struct hashset * target); _Bool hs_iter_at_start(struct hashset_iter * iter); _Bool hs_iter_at_end(struct hashset_iter * iter); _Bool hs_iter_to_start(struct hashset_iter * iter); _Bool hs_iter_to_end(struct hashset_iter * iter); _Bool hs_iter_next(struct hashset_iter * iter); _Bool hs_iter_prev(struct hashset_iter * iter); _Bool hs_iter_advance(struct hashset_iter * iter, size_t steps); _Bool hs_iter_rewind(struct hashset_iter * iter, size_t steps); _Bool hs_iter_go_to(struct hashset_iter * iter, size_t index); size_t hs_iter_value(struct hashset_iter * iter); size_t hs_iter_index(struct hashset_iter * iter); struct hashset *hs_union(struct hashset * _set1_, struct hashset * _set2_); struct hashset *hs_intersection(struct hashset * _set1_, struct hashset * _set2_); struct hashset *hs_difference(struct hashset * _set1_, struct hashset * _set2_); struct hashset *hs_symmetric_difference(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_subset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_superset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_proper_subset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_proper_superset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_disjointset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_to_string(struct hashset * _set_, FILE * fptr); _Bool hs_print(struct hashset * _set_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_HASHSET_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_heap.h b/tests/include/tst_cmc_heap.h new file mode 100644 index 0000000..73aa0c6 --- /dev/null +++ b/tests/include/tst_cmc_heap.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_HEAP_TEST_H + #define CMC_CMC_HEAP_TEST_H + + #include "macro_collections.h" + + struct heap { size_t *buffer; size_t capacity; size_t count; enum cmc_heap_order HO; int flag; struct heap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct heap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval * f_val); struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void h_clear(struct heap * _heap_); void h_free(struct heap * _heap_); void h_customize(struct heap * _heap_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool h_insert(struct heap * _heap_, size_t value); _Bool h_remove(struct heap * _heap_); size_t h_peek(struct heap * _heap_); _Bool h_contains(struct heap * _heap_, size_t value); _Bool h_empty(struct heap * _heap_); _Bool h_full(struct heap * _heap_); size_t h_count(struct heap * _heap_); size_t h_capacity(struct heap * _heap_); int h_flag(struct heap * _heap_); _Bool h_resize(struct heap * _heap_, size_t capacity); struct heap *h_copy_of(struct heap * _heap_); _Bool h_equals(struct heap * _heap1_, struct heap * _heap2_); struct heap_iter { struct heap *target; size_t cursor; _Bool start; _Bool end; }; struct heap_iter h_iter_start(struct heap * target); struct heap_iter h_iter_end(struct heap * target); _Bool h_iter_at_start(struct heap_iter * iter); _Bool h_iter_at_end(struct heap_iter * iter); _Bool h_iter_to_start(struct heap_iter * iter); _Bool h_iter_to_end(struct heap_iter * iter); _Bool h_iter_next(struct heap_iter * iter); _Bool h_iter_prev(struct heap_iter * iter); _Bool h_iter_advance(struct heap_iter * iter, size_t steps); _Bool h_iter_rewind(struct heap_iter * iter, size_t steps); _Bool h_iter_go_to(struct heap_iter * iter, size_t index); size_t h_iter_value(struct heap_iter * iter); size_t h_iter_index(struct heap_iter * iter); _Bool h_to_string(struct heap * _heap_, FILE * fptr); _Bool h_print(struct heap * _heap_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_HEAP_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_intervalheap.h b/tests/include/tst_cmc_intervalheap.h new file mode 100644 index 0000000..28b3010 --- /dev/null +++ b/tests/include/tst_cmc_intervalheap.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_INTERVALHEAP_TEST_H + #define CMC_CMC_INTERVALHEAP_TEST_H + + #include "macro_collections.h" + + struct intervalheap { size_t (*buffer)[2]; size_t capacity; size_t size; size_t count; int flag; struct intervalheap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct intervalheap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval * f_val); struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void ih_clear(struct intervalheap * _heap_); void ih_free(struct intervalheap * _heap_); void ih_customize(struct intervalheap * _heap_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool ih_insert(struct intervalheap * _heap_, size_t value); _Bool ih_remove_max(struct intervalheap * _heap_); _Bool ih_remove_min(struct intervalheap * _heap_); _Bool ih_update_max(struct intervalheap * _heap_, size_t value); _Bool ih_update_min(struct intervalheap * _heap_, size_t value); size_t ih_max(struct intervalheap * _heap_); size_t ih_min(struct intervalheap * _heap_); _Bool ih_contains(struct intervalheap * _heap_, size_t value); _Bool ih_empty(struct intervalheap * _heap_); _Bool ih_full(struct intervalheap * _heap_); size_t ih_count(struct intervalheap * _heap_); size_t ih_capacity(struct intervalheap * _heap_); int ih_flag(struct intervalheap * _heap_); _Bool ih_resize(struct intervalheap * _heap_, size_t capacity); struct intervalheap *ih_copy_of(struct intervalheap * _heap_); _Bool ih_equals(struct intervalheap * _heap1_, struct intervalheap * _heap2_); struct intervalheap_iter { struct intervalheap *target; size_t cursor; _Bool start; _Bool end; }; struct intervalheap_iter ih_iter_start(struct intervalheap * target); struct intervalheap_iter ih_iter_end(struct intervalheap * target); _Bool ih_iter_at_start(struct intervalheap_iter * iter); _Bool ih_iter_at_end(struct intervalheap_iter * iter); _Bool ih_iter_to_start(struct intervalheap_iter * iter); _Bool ih_iter_to_end(struct intervalheap_iter * iter); _Bool ih_iter_next(struct intervalheap_iter * iter); _Bool ih_iter_prev(struct intervalheap_iter * iter); _Bool ih_iter_advance(struct intervalheap_iter * iter, size_t steps); _Bool ih_iter_rewind(struct intervalheap_iter * iter, size_t steps); _Bool ih_iter_go_to(struct intervalheap_iter * iter, size_t index); size_t ih_iter_value(struct intervalheap_iter * iter); size_t ih_iter_index(struct intervalheap_iter * iter); _Bool ih_to_string(struct intervalheap * _heap_, FILE * fptr); _Bool ih_print(struct intervalheap * _heap_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_INTERVALHEAP_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_linkedlist.h b/tests/include/tst_cmc_linkedlist.h new file mode 100644 index 0000000..e682e9e --- /dev/null +++ b/tests/include/tst_cmc_linkedlist.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_LINKEDLIST_TEST_H + #define CMC_CMC_LINKEDLIST_TEST_H + + #include "macro_collections.h" + + struct linkedlist { struct linkedlist_node * head; struct linkedlist_node * tail; size_t count; int flag; struct linkedlist_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct linkedlist_node { size_t value; struct linkedlist_node * next; struct linkedlist_node * prev; }; struct linkedlist_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct linkedlist *ll_new(struct linkedlist_fval * f_val); struct linkedlist *ll_new_custom(struct linkedlist_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void ll_clear(struct linkedlist * _list_); void ll_free(struct linkedlist * _list_); void ll_customize(struct linkedlist * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool ll_push_front(struct linkedlist * _list_, size_t value); _Bool ll_push_at(struct linkedlist * _list_, size_t value, size_t index); _Bool ll_push_back(struct linkedlist * _list_, size_t value); _Bool ll_pop_front(struct linkedlist * _list_); _Bool ll_pop_at(struct linkedlist * _list_, size_t index); _Bool ll_pop_back(struct linkedlist * _list_); size_t ll_front(struct linkedlist * _list_); size_t ll_get(struct linkedlist * _list_, size_t index); size_t *ll_get_ref(struct linkedlist * _list_, size_t index); size_t ll_back(struct linkedlist * _list_); _Bool ll_contains(struct linkedlist * _list_, size_t value); _Bool ll_empty(struct linkedlist * _list_); size_t ll_count(struct linkedlist * _list_); int ll_flag(struct linkedlist * _list_); struct linkedlist *ll_copy_of(struct linkedlist * _list_); _Bool ll_equals(struct linkedlist * _list1_, struct linkedlist * _list2_); struct linkedlist_iter { struct linkedlist *target; struct linkedlist_node * cursor; size_t index; _Bool start; _Bool end; }; struct linkedlist_iter ll_iter_start(struct linkedlist * target); struct linkedlist_iter ll_iter_end(struct linkedlist * target); _Bool ll_iter_at_start(struct linkedlist_iter * iter); _Bool ll_iter_at_end(struct linkedlist_iter * iter); _Bool ll_iter_to_start(struct linkedlist_iter * iter); _Bool ll_iter_to_end(struct linkedlist_iter * iter); _Bool ll_iter_next(struct linkedlist_iter * iter); _Bool ll_iter_prev(struct linkedlist_iter * iter); _Bool ll_iter_advance(struct linkedlist_iter * iter, size_t steps); _Bool ll_iter_rewind(struct linkedlist_iter * iter, size_t steps); _Bool ll_iter_go_to(struct linkedlist_iter * iter, size_t index); size_t ll_iter_value(struct linkedlist_iter * iter); size_t *ll_iter_rvalue(struct linkedlist_iter * iter); size_t ll_iter_index(struct linkedlist_iter * iter); struct linkedlist_node * ll_iter_node(struct linkedlist_iter * iter); struct linkedlist_node * ll_new_node(struct linkedlist * _list_, size_t value); void ll_free_node(struct linkedlist * _list_, struct linkedlist_node * _node_); struct linkedlist_node * ll_head(struct linkedlist * _list_); struct linkedlist_node * ll_get_node(struct linkedlist * _list_, size_t index); struct linkedlist_node * ll_tail(struct linkedlist * _list_); _Bool ll_add_next(struct linkedlist * _owner_, struct linkedlist_node * _node_, size_t value); _Bool ll_add_prev(struct linkedlist * _owner_, struct linkedlist_node * _node_, size_t value); _Bool ll_del_next(struct linkedlist * _owner_, struct linkedlist_node * _node_); _Bool ll_del_curr(struct linkedlist * _owner_, struct linkedlist_node * _node_); _Bool ll_del_prev(struct linkedlist * _owner_, struct linkedlist_node * _node_); struct linkedlist_node * ll_next_node(struct linkedlist_node * _node_); struct linkedlist_node * ll_prev_node(struct linkedlist_node * _node_); _Bool ll_to_string(struct linkedlist * _list_, FILE * fptr); _Bool ll_print(struct linkedlist * _list_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_LINKEDLIST_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_list.h b/tests/include/tst_cmc_list.h new file mode 100644 index 0000000..f7def9b --- /dev/null +++ b/tests/include/tst_cmc_list.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_LIST_TEST_H + #define CMC_CMC_LIST_TEST_H + + #include "macro_collections.h" + + struct list { size_t *buffer; size_t capacity; size_t count; int flag; struct list_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct list_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct list *l_new(size_t capacity, struct list_fval * f_val); struct list *l_new_custom(size_t capacity, struct list_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void l_clear(struct list * _list_); void l_free(struct list * _list_); void l_customize(struct list * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool l_push_front(struct list * _list_, size_t value); _Bool l_push_at(struct list * _list_, size_t value, size_t index); _Bool l_push_back(struct list * _list_, size_t value); _Bool l_pop_front(struct list * _list_); _Bool l_pop_at(struct list * _list_, size_t index); _Bool l_pop_back(struct list * _list_); size_t l_front(struct list * _list_); size_t l_get(struct list * _list_, size_t index); size_t *l_get_ref(struct list * _list_, size_t index); size_t l_back(struct list * _list_); size_t l_index_of(struct list * _list_, size_t value, _Bool from_start); _Bool l_contains(struct list * _list_, size_t value); _Bool l_empty(struct list * _list_); _Bool l_full(struct list * _list_); size_t l_count(struct list * _list_); _Bool l_fits(struct list * _list_, size_t size); size_t l_capacity(struct list * _list_); int l_flag(struct list * _list_); _Bool l_resize(struct list * _list_, size_t capacity); struct list *l_copy_of(struct list * _list_); _Bool l_equals(struct list * _list1_, struct list * _list2_); struct list_iter { struct list *target; size_t cursor; _Bool start; _Bool end; }; struct list_iter l_iter_start(struct list * target); struct list_iter l_iter_end(struct list * target); _Bool l_iter_at_start(struct list_iter * iter); _Bool l_iter_at_end(struct list_iter * iter); _Bool l_iter_to_start(struct list_iter * iter); _Bool l_iter_to_end(struct list_iter * iter); _Bool l_iter_next(struct list_iter * iter); _Bool l_iter_prev(struct list_iter * iter); _Bool l_iter_advance(struct list_iter * iter, size_t steps); _Bool l_iter_rewind(struct list_iter * iter, size_t steps); _Bool l_iter_go_to(struct list_iter * iter, size_t index); size_t l_iter_value(struct list_iter * iter); size_t *l_iter_rvalue(struct list_iter * iter); size_t l_iter_index(struct list_iter * iter); _Bool l_seq_push_front(struct list * _list_, size_t * values, size_t size); _Bool l_seq_push_at(struct list * _list_, size_t * values, size_t size, size_t index); _Bool l_seq_push_back(struct list * _list_, size_t * values, size_t size); _Bool l_seq_pop_at(struct list * _list_, size_t from, size_t to); struct list *l_seq_sublist(struct list * _list_, size_t from, size_t to); _Bool l_to_string(struct list * _list_, FILE * fptr); _Bool l_print(struct list * _list_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_LIST_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_queue.h b/tests/include/tst_cmc_queue.h new file mode 100644 index 0000000..6cdcdc0 --- /dev/null +++ b/tests/include/tst_cmc_queue.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_QUEUE_TEST_H + #define CMC_CMC_QUEUE_TEST_H + + #include "macro_collections.h" + + struct queue { size_t *buffer; size_t capacity; size_t count; size_t front; size_t back; int flag; struct queue_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct queue_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct queue *q_new(size_t capacity, struct queue_fval * f_val); struct queue *q_new_custom(size_t capacity, struct queue_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void q_clear(struct queue * _queue_); void q_free(struct queue * _queue_); void q_customize(struct queue * _queue_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool q_enqueue(struct queue * _queue_, size_t value); _Bool q_dequeue(struct queue * _queue_); size_t q_peek(struct queue * _queue_); _Bool q_contains(struct queue * _queue_, size_t value); _Bool q_empty(struct queue * _queue_); _Bool q_full(struct queue * _queue_); size_t q_count(struct queue * _queue_); size_t q_capacity(struct queue * _queue_); int q_flag(struct queue * _queue_); _Bool q_resize(struct queue * _queue_, size_t capacity); struct queue *q_copy_of(struct queue * _queue_); _Bool q_equals(struct queue * _queue1_, struct queue * _queue2_); struct queue_iter { struct queue *target; size_t cursor; size_t index; _Bool start; _Bool end; }; struct queue_iter q_iter_start(struct queue * target); struct queue_iter q_iter_end(struct queue * target); _Bool q_iter_at_start(struct queue_iter * iter); _Bool q_iter_at_end(struct queue_iter * iter); _Bool q_iter_to_start(struct queue_iter * iter); _Bool q_iter_to_end(struct queue_iter * iter); _Bool q_iter_next(struct queue_iter * iter); _Bool q_iter_prev(struct queue_iter * iter); _Bool q_iter_advance(struct queue_iter * iter, size_t steps); _Bool q_iter_rewind(struct queue_iter * iter, size_t steps); _Bool q_iter_go_to(struct queue_iter * iter, size_t index); size_t q_iter_value(struct queue_iter * iter); size_t *q_iter_rvalue(struct queue_iter * iter); size_t q_iter_index(struct queue_iter * iter); _Bool q_to_string(struct queue * _queue_, FILE * fptr); _Bool q_print(struct queue * _queue_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_QUEUE_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_sortedlist.h b/tests/include/tst_cmc_sortedlist.h new file mode 100644 index 0000000..2b4e0bf --- /dev/null +++ b/tests/include/tst_cmc_sortedlist.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_SORTEDLIST_TEST_H + #define CMC_CMC_SORTEDLIST_TEST_H + + #include "macro_collections.h" + + struct sortedlist { size_t *buffer; size_t capacity; size_t count; _Bool is_sorted; int flag; struct sortedlist_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct sortedlist_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval * f_val); struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void sl_clear(struct sortedlist * _list_); void sl_free(struct sortedlist * _list_); void sl_customize(struct sortedlist * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool sl_insert(struct sortedlist * _list_, size_t value); _Bool sl_remove(struct sortedlist * _list_, size_t index); size_t sl_max(struct sortedlist * _list_); size_t sl_min(struct sortedlist * _list_); size_t sl_get(struct sortedlist * _list_, size_t index); size_t sl_index_of(struct sortedlist * _list_, size_t value, _Bool from_start); _Bool sl_contains(struct sortedlist * _list_, size_t value); _Bool sl_empty(struct sortedlist * _list_); _Bool sl_full(struct sortedlist * _list_); size_t sl_count(struct sortedlist * _list_); size_t sl_capacity(struct sortedlist * _list_); int sl_flag(struct sortedlist * _list_); _Bool sl_resize(struct sortedlist * _list_, size_t capacity); void sl_sort(struct sortedlist * _list_); struct sortedlist *sl_copy_of(struct sortedlist * _list_); _Bool sl_equals(struct sortedlist * _list1_, struct sortedlist * _list2_); struct sortedlist_iter { struct sortedlist *target; size_t cursor; _Bool start; _Bool end; }; struct sortedlist_iter sl_iter_start(struct sortedlist * target); struct sortedlist_iter sl_iter_end(struct sortedlist * target); _Bool sl_iter_at_start(struct sortedlist_iter * iter); _Bool sl_iter_at_end(struct sortedlist_iter * iter); _Bool sl_iter_to_start(struct sortedlist_iter * iter); _Bool sl_iter_to_end(struct sortedlist_iter * iter); _Bool sl_iter_next(struct sortedlist_iter * iter); _Bool sl_iter_prev(struct sortedlist_iter * iter); _Bool sl_iter_advance(struct sortedlist_iter * iter, size_t steps); _Bool sl_iter_rewind(struct sortedlist_iter * iter, size_t steps); _Bool sl_iter_go_to(struct sortedlist_iter * iter, size_t index); size_t sl_iter_value(struct sortedlist_iter * iter); size_t sl_iter_index(struct sortedlist_iter * iter); _Bool sl_to_string(struct sortedlist * _list_, FILE * fptr); _Bool sl_print(struct sortedlist * _list_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_SORTEDLIST_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_stack.h b/tests/include/tst_cmc_stack.h new file mode 100644 index 0000000..0def578 --- /dev/null +++ b/tests/include/tst_cmc_stack.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_STACK_TEST_H + #define CMC_CMC_STACK_TEST_H + + #include "macro_collections.h" + + struct stack { size_t *buffer; size_t capacity; size_t count; int flag; struct stack_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct stack_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct stack *s_new(size_t capacity, struct stack_fval * f_val); struct stack *s_new_custom(size_t capacity, struct stack_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void s_clear(struct stack * _stack_); void s_free(struct stack * _stack_); void s_customize(struct stack * _stack_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool s_push(struct stack * _stack_, size_t value); _Bool s_pop(struct stack * _stack_); size_t s_top(struct stack * _stack_); _Bool s_contains(struct stack * _stack_, size_t value); _Bool s_empty(struct stack * _stack_); _Bool s_full(struct stack * _stack_); size_t s_count(struct stack * _stack_); size_t s_capacity(struct stack * _stack_); int s_flag(struct stack * _stack_); _Bool s_resize(struct stack * _stack_, size_t capacity); struct stack *s_copy_of(struct stack * _stack_); _Bool s_equals(struct stack * _stack1_, struct stack * _stack2_); struct stack_iter { struct stack *target; size_t cursor; _Bool start; _Bool end; }; struct stack_iter s_iter_start(struct stack * target); struct stack_iter s_iter_end(struct stack * target); _Bool s_iter_at_start(struct stack_iter * iter); _Bool s_iter_at_end(struct stack_iter * iter); _Bool s_iter_to_start(struct stack_iter * iter); _Bool s_iter_to_end(struct stack_iter * iter); _Bool s_iter_next(struct stack_iter * iter); _Bool s_iter_prev(struct stack_iter * iter); _Bool s_iter_advance(struct stack_iter * iter, size_t steps); _Bool s_iter_rewind(struct stack_iter * iter, size_t steps); _Bool s_iter_go_to(struct stack_iter * iter, size_t index); size_t s_iter_value(struct stack_iter * iter); size_t *s_iter_rvalue(struct stack_iter * iter); size_t s_iter_index(struct stack_iter * iter); _Bool s_to_string(struct stack * _stack_, FILE * fptr); _Bool s_print(struct stack * _stack_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_STACK_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_treemap.h b/tests/include/tst_cmc_treemap.h new file mode 100644 index 0000000..d13e622 --- /dev/null +++ b/tests/include/tst_cmc_treemap.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_TREEMAP_TEST_H + #define CMC_CMC_TREEMAP_TEST_H + + #include "macro_collections.h" + + struct treemap { struct treemap_node * root; size_t count; int flag; struct treemap_fkey * f_key; struct treemap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct treemap_node { size_t key; size_t value; unsigned char height; struct treemap_node * right; struct treemap_node * left; struct treemap_node * parent; }; struct treemap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct treemap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct treemap *tm_new(struct treemap_fkey * f_key, struct treemap_fval * f_val); struct treemap *tm_new_custom(struct treemap_fkey * f_key, struct treemap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void tm_clear(struct treemap * _map_); void tm_free(struct treemap * _map_); void tm_customize(struct treemap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool tm_insert(struct treemap * _map_, size_t key, size_t value); _Bool tm_update(struct treemap * _map_, size_t key, size_t new_value, size_t * old_value); _Bool tm_remove(struct treemap * _map_, size_t key, size_t * out_value); _Bool tm_max(struct treemap * _map_, size_t * key, size_t * value); _Bool tm_min(struct treemap * _map_, size_t * key, size_t * value); size_t tm_get(struct treemap * _map_, size_t key); size_t *tm_get_ref(struct treemap * _map_, size_t key); _Bool tm_contains(struct treemap * _map_, size_t key); _Bool tm_empty(struct treemap * _map_); size_t tm_count(struct treemap * _map_); int tm_flag(struct treemap * _map_); struct treemap *tm_copy_of(struct treemap * _map_); _Bool tm_equals(struct treemap * _map1_, struct treemap * _map2_); struct treemap_iter { struct treemap *target; struct treemap_node * cursor; struct treemap_node * first; struct treemap_node * last; size_t index; _Bool start; _Bool end; }; struct treemap_iter tm_iter_start(struct treemap * target); struct treemap_iter tm_iter_end(struct treemap * target); _Bool tm_iter_at_start(struct treemap_iter * iter); _Bool tm_iter_at_end(struct treemap_iter * iter); _Bool tm_iter_to_start(struct treemap_iter * iter); _Bool tm_iter_to_end(struct treemap_iter * iter); _Bool tm_iter_next(struct treemap_iter * iter); _Bool tm_iter_prev(struct treemap_iter * iter); _Bool tm_iter_advance(struct treemap_iter * iter, size_t steps); _Bool tm_iter_rewind(struct treemap_iter * iter, size_t steps); _Bool tm_iter_go_to(struct treemap_iter * iter, size_t index); size_t tm_iter_key(struct treemap_iter * iter); size_t tm_iter_value(struct treemap_iter * iter); size_t *tm_iter_rvalue(struct treemap_iter * iter); size_t tm_iter_index(struct treemap_iter * iter); _Bool tm_to_string(struct treemap * _map_, FILE * fptr); _Bool tm_print(struct treemap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); + + + #endif /* CMC_CMC_TREEMAP_TEST_H */ + \ No newline at end of file diff --git a/tests/include/tst_cmc_treeset.h b/tests/include/tst_cmc_treeset.h new file mode 100644 index 0000000..3623f97 --- /dev/null +++ b/tests/include/tst_cmc_treeset.h @@ -0,0 +1,11 @@ + + #ifndef CMC_CMC_TREESET_TEST_H + #define CMC_CMC_TREESET_TEST_H + + #include "macro_collections.h" + + struct treeset { struct treeset_node * root; size_t count; int flag; struct treeset_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct treeset_node { size_t value; unsigned char height; struct treeset_node * right; struct treeset_node * left; struct treeset_node * parent; }; struct treeset_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct treeset *ts_new(struct treeset_fval * f_val); struct treeset *ts_new_custom(struct treeset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void ts_clear(struct treeset * _set_); void ts_free(struct treeset * _set_); void ts_customize(struct treeset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool ts_insert(struct treeset * _set_, size_t value); _Bool ts_remove(struct treeset * _set_, size_t value); _Bool ts_max(struct treeset * _set_, size_t * value); _Bool ts_min(struct treeset * _set_, size_t * value); _Bool ts_contains(struct treeset * _set_, size_t value); _Bool ts_empty(struct treeset * _set_); size_t ts_count(struct treeset * _set_); int ts_flag(struct treeset * _set_); struct treeset *ts_copy_of(struct treeset * _set_); _Bool ts_equals(struct treeset * _set1_, struct treeset * _set2_); struct treeset_iter { struct treeset *target; struct treeset_node * cursor; struct treeset_node * first; struct treeset_node * last; size_t index; _Bool start; _Bool end; }; struct treeset_iter ts_iter_start(struct treeset * target); struct treeset_iter ts_iter_end(struct treeset * target); _Bool ts_iter_at_start(struct treeset_iter * iter); _Bool ts_iter_at_end(struct treeset_iter * iter); _Bool ts_iter_to_start(struct treeset_iter * iter); _Bool ts_iter_to_end(struct treeset_iter * iter); _Bool ts_iter_next(struct treeset_iter * iter); _Bool ts_iter_prev(struct treeset_iter * iter); _Bool ts_iter_advance(struct treeset_iter * iter, size_t steps); _Bool ts_iter_rewind(struct treeset_iter * iter, size_t steps); _Bool ts_iter_go_to(struct treeset_iter * iter, size_t index); size_t ts_iter_value(struct treeset_iter * iter); size_t ts_iter_index(struct treeset_iter * iter); struct treeset *ts_union(struct treeset * _set1_, struct treeset * _set2_); struct treeset *ts_intersection(struct treeset * _set1_, struct treeset * _set2_); struct treeset *ts_difference(struct treeset * _set1_, struct treeset * _set2_); struct treeset *ts_symmetric_difference(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_subset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_superset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_proper_subset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_proper_superset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_disjointset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_to_string(struct treeset * _set_, FILE * fptr); _Bool ts_print(struct treeset * _set_, FILE * fptr, const char *start, const char *separator, const char *end); + + + #endif /* CMC_CMC_TREESET_TEST_H */ + \ No newline at end of file diff --git a/tests/main.c b/tests/main.c index 4007f43..61d40c7 100644 --- a/tests/main.c +++ b/tests/main.c @@ -1,29 +1,29 @@ #include #include -#include "unt/cmc/bitset.h" -#include "unt/cmc/deque.h" -#include "unt/cmc/hashbidimap.h" -#include "unt/cmc/hashmap.h" -#include "unt/cmc/hashmultimap.h" -#include "unt/cmc/hashmultiset.h" -#include "unt/cmc/hashset.h" -#include "unt/cmc/heap.h" -#include "unt/cmc/intervalheap.h" -#include "unt/cmc/linkedlist.h" -#include "unt/cmc/list.h" -#include "unt/cmc/queue.h" -#include "unt/cmc/sortedlist.h" -#include "unt/cmc/stack.h" -#include "unt/cmc/treemap.h" -#include "unt/cmc/treeset.h" +#include "unt_cmc_bitset.h" +#include "unt_cmc_deque.h" +#include "unt_cmc_hashbidimap.h" +#include "unt_cmc_hashmap.h" +#include "unt_cmc_hashmultimap.h" +#include "unt_cmc_hashmultiset.h" +#include "unt_cmc_hashset.h" +#include "unt_cmc_heap.h" +#include "unt_cmc_intervalheap.h" +#include "unt_cmc_linkedlist.h" +#include "unt_cmc_list.h" +#include "unt_cmc_queue.h" +#include "unt_cmc_sortedlist.h" +#include "unt_cmc_stack.h" +#include "unt_cmc_treemap.h" +#include "unt_cmc_treeset.h" -#include "unt/utl/foreach.h" +#include "unt_utl_foreach.h" -#include "utl/assert.h" -#include "utl/timer.h" +#include "utl_assert.h" +#include "utl_timer.h" -#include "./unt/utl.h" +#include "utl.h" #define cmc_run(unit, unit_fails, test_fails) \ do \ diff --git a/tests/src/cmc/bitset.c b/tests/src/cmc/bitset.c deleted file mode 100644 index 39865ba..0000000 --- a/tests/src/cmc/bitset.c +++ /dev/null @@ -1,294 +0,0 @@ - -#include "cmc/bitset.h" - -_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize); -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) -{ - ; - if (n_bits < 1) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; - struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset)); - if (!_bitset_) - return ((void *)0); - _bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); - if (!_bitset_->buffer) - { - alloc->free(_bitset_); - return ((void *)0); - } - _bitset_->capacity = capacity; - _bitset_->flag = CMC_FLAG_OK; - _bitset_->alloc = alloc; - (_bitset_)->callbacks = callbacks; - return _bitset_; -} -struct bitset bs_init(size_t n_bits) -{ - return bs_init_custom(n_bits, ((void *)0), ((void *)0)); -} -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, - struct cmc_callbacks *__attribute__((__unused__)) (callbacks)) -{ - ; - struct bitset _bitset_ = { 0 }; - if (n_bits < 1) - return _bitset_; - if (!alloc) - alloc = &cmc_alloc_node_default; - size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; - _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); - if (!_bitset_.buffer) - return _bitset_; - _bitset_.capacity = capacity; - _bitset_.flag = CMC_FLAG_OK; - _bitset_.alloc = alloc; - (&_bitset_)->callbacks = callbacks; - return _bitset_; -} -void bs_free(struct bitset *_bitset_) -{ - free(_bitset_->buffer); - free(_bitset_); -} -void bs_release(struct bitset _bitset_) -{ - free(_bitset_.buffer); -} -void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _bitset_->alloc = &cmc_alloc_node_default; - else - _bitset_->alloc = alloc; - (_bitset_)->callbacks = callbacks; - _bitset_->flag = CMC_FLAG_OK; -} -_Bool bs_set(struct bitset *_bitset_, size_t bit_index) -{ - if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) - return 0; - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = cmc_bidx_to_widx(bit_index); - _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) - (_bitset_)->callbacks->create(); - ; - return 1; -} -_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) -{ - if (to < from) - { - _bitset_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!bs_impl_resize(_bitset_, to + 1, 0)) - return 0; - size_t start_index = cmc_bidx_to_widx(from); - size_t end_index = cmc_bidx_to_widx(to); - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - const cmc_bitset_word ones = ~((cmc_bitset_word)0); - cmc_bitset_word shift_start = from % bits; - 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 1; -} -_Bool bs_clear(struct bitset *_bitset_, size_t bit_index) -{ - if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) - return 0; - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = cmc_bidx_to_widx(bit_index); - _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) - (_bitset_)->callbacks->delete (); - ; - return 1; -} -_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) -{ - if (to < from) - { - _bitset_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!bs_impl_resize(_bitset_, to + 1, 0)) - return 0; - size_t start_index = cmc_bidx_to_widx(from); - size_t end_index = cmc_bidx_to_widx(to); - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - const cmc_bitset_word ones = ~((cmc_bitset_word)0); - cmc_bitset_word shift_start = from % bits; - 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 1; -} -_Bool bs_flip(struct bitset *_bitset_, size_t bit_index) -{ - if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) - return 0; - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = cmc_bidx_to_widx(bit_index); - _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) - (_bitset_)->callbacks->update(); - ; - return 1; -} -_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) -{ - if (to < from) - { - _bitset_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!bs_impl_resize(_bitset_, to + 1, 0)) - return 0; - size_t start_index = cmc_bidx_to_widx(from); - size_t end_index = cmc_bidx_to_widx(to); - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - const cmc_bitset_word ones = ~((cmc_bitset_word)0); - cmc_bitset_word shift_start = from % bits; - 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 1; -} -_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state) -{ - if (state) - return bs_set(_bitset_, bit_index); - else - return bs_clear(_bitset_, bit_index); -} -_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state) -{ - if (state) - return bs_set_range(_bitset_, from, to); - else - return bs_clear_range(_bitset_, from, to); -} -_Bool bs_set_all(struct bitset *_bitset_) -{ - for (size_t i = 0; i < _bitset_->capacity; i++) - _bitset_->buffer[i] = ~((cmc_bitset_word)0); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) - (_bitset_)->callbacks->create(); - ; - return 1; -} -_Bool bs_clear_all(struct bitset *_bitset_) -{ - for (size_t i = 0; i < _bitset_->capacity; i++) - _bitset_->buffer[i] = 0; - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) - (_bitset_)->callbacks->delete (); - ; - return 1; -} -_Bool bs_flip_all(struct bitset *_bitset_) -{ - for (size_t i = 0; i < _bitset_->capacity; i++) - _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) - (_bitset_)->callbacks->create(); - ; - return 1; -} -_Bool bs_get(struct bitset *_bitset_, size_t bit_index) -{ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; - return w & ((cmc_bitset_word)1 << (bit_index % bits)); -} -_Bool bs_resize(struct bitset *_bitset_, size_t n_bits) -{ - return bs_impl_resize(_bitset_, n_bits, 1); -} -_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) -{ - if (n_bits == 0) - { - _bitset_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; - if (!do_resize && words <= _bitset_->capacity) - return 1; - cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); - if (!new_buffer) - { - _bitset_->flag = CMC_FLAG_ALLOC; - return 0; - } - _bitset_->buffer = new_buffer; - 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 1; -} diff --git a/tests/src/cmc/deque.c b/tests/src/cmc/deque.c deleted file mode 100644 index ede6e29..0000000 --- a/tests/src/cmc/deque.c +++ /dev/null @@ -1,516 +0,0 @@ - -#include "cmc/deque.h" - -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 cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct deque *_deque_ = alloc->malloc(sizeof(struct deque)); - if (!_deque_) - return ((void *)0); - _deque_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_deque_->buffer) - { - alloc->free(_deque_); - return ((void *)0); - } - _deque_->capacity = capacity; - _deque_->count = 0; - _deque_->front = 0; - _deque_->back = 0; - _deque_->flag = CMC_FLAG_OK; - _deque_->f_val = f_val; - _deque_->alloc = alloc; - (_deque_)->callbacks = callbacks; - return _deque_; -} -void d_clear(struct deque *_deque_) -{ - if (_deque_->f_val->free) - { - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - _deque_->f_val->free(_deque_->buffer[i]); - i = (i + 1) % _deque_->capacity; - } - } - memset(_deque_->buffer, 0, sizeof(size_t) * _deque_->capacity); - _deque_->count = 0; - _deque_->front = 0; - _deque_->back = 0; - _deque_->flag = CMC_FLAG_OK; -} -void d_free(struct deque *_deque_) -{ - if (_deque_->f_val->free) - { - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - _deque_->f_val->free(_deque_->buffer[i]); - i = (i + 1) % _deque_->capacity; - } - } - _deque_->alloc->free(_deque_->buffer); - _deque_->alloc->free(_deque_); -} -void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _deque_->alloc = &cmc_alloc_node_default; - else - _deque_->alloc = alloc; - (_deque_)->callbacks = callbacks; - _deque_->flag = CMC_FLAG_OK; -} -_Bool d_push_front(struct deque *_deque_, size_t value) -{ - if (d_full(_deque_)) - { - if (!d_resize(_deque_, _deque_->capacity * 2)) - return 0; - } - _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 1; -} -_Bool d_push_back(struct deque *_deque_, size_t value) -{ - if (d_full(_deque_)) - { - if (!d_resize(_deque_, _deque_->capacity * 2)) - return 0; - } - _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 1; -} -_Bool d_pop_front(struct deque *_deque_) -{ - if (d_empty(_deque_)) - { - _deque_->flag = CMC_FLAG_EMPTY; - return 0; - } - _deque_->buffer[_deque_->front] = (size_t){ 0 }; - _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; - _deque_->count--; - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->delete) - (_deque_)->callbacks->delete (); - ; - return 1; -} -_Bool d_pop_back(struct deque *_deque_) -{ - if (d_empty(_deque_)) - { - _deque_->flag = CMC_FLAG_EMPTY; - return 0; - } - _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; - _deque_->buffer[_deque_->back] = (size_t){ 0 }; - _deque_->count--; - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->delete) - (_deque_)->callbacks->delete (); - ; - return 1; -} -size_t d_front(struct deque *_deque_) -{ - if (d_empty(_deque_)) - { - _deque_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->read) - (_deque_)->callbacks->read(); - ; - return _deque_->buffer[_deque_->front]; -} -size_t d_back(struct deque *_deque_) -{ - if (d_empty(_deque_)) - { - _deque_->flag = CMC_FLAG_EMPTY; - return (size_t){ 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 d_contains(struct deque *_deque_, size_t value) -{ - _deque_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) - { - result = 1; - break; - } - i = (i + 1) % _deque_->capacity; - } - if ((_deque_)->callbacks && (_deque_)->callbacks->read) - (_deque_)->callbacks->read(); - ; - return result; -} -_Bool d_empty(struct deque *_deque_) -{ - return _deque_->count == 0; -} -_Bool d_full(struct deque *_deque_) -{ - return _deque_->count >= _deque_->capacity; -} -size_t d_count(struct deque *_deque_) -{ - return _deque_->count; -} -size_t d_capacity(struct deque *_deque_) -{ - return _deque_->capacity; -} -int d_flag(struct deque *_deque_) -{ - return _deque_->flag; -} -_Bool d_resize(struct deque *_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 0; - } - size_t *new_buffer = _deque_->alloc->malloc(sizeof(size_t) * capacity); - if (!new_buffer) - { - _deque_->flag = CMC_FLAG_ALLOC; - return 0; - } - 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 1; -} -struct deque *d_copy_of(struct deque *_deque_) -{ - struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0)); - if (!result) - { - _deque_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _deque_->callbacks; - if (_deque_->f_val->cpy) - { - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - 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 d_equals(struct deque *_deque1_, struct deque *_deque2_) -{ - _deque1_->flag = CMC_FLAG_OK; - _deque2_->flag = CMC_FLAG_OK; - 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++) - { - if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) - return 0; - i = (i + 1) % _deque1_->capacity; - j = (j + 1) % _deque2_->capacity; - } - return 1; -} -struct deque d_init(size_t capacity, struct deque_fval *f_val) -{ - return d_init_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - struct deque _deque_ = { 0 }; - if (capacity < 1) - return _deque_; - if (!f_val) - return _deque_; - if (!alloc) - alloc = &cmc_alloc_node_default; - _deque_.buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_deque_.buffer) - return _deque_; - _deque_.capacity = capacity; - _deque_.count = 0; - _deque_.front = 0; - _deque_.back = 0; - _deque_.flag = CMC_FLAG_OK; - _deque_.f_val = f_val; - _deque_.alloc = alloc; - (&_deque_)->callbacks = callbacks; - return _deque_; -} -void d_release(struct deque _deque_) -{ - if (_deque_.f_val->free) - { - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) - { - _deque_.f_val->free(_deque_.buffer[i]); - i = (i + 1) % _deque_.capacity; - } - } - _deque_.alloc->free(_deque_.buffer); -} -struct deque_iter d_iter_start(struct deque *target) -{ - struct deque_iter iter; - iter.target = target; - iter.cursor = target->front; - iter.index = 0; - iter.start = 1; - iter.end = d_empty(target); - return iter; -} -struct deque_iter d_iter_end(struct deque *target) -{ - struct deque_iter iter; - iter.target = target; - if (!d_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 = d_empty(target); - iter.end = 1; - return iter; -} -_Bool d_iter_at_start(struct deque_iter *iter) -{ - return d_empty(iter->target) || iter->start; -} -_Bool d_iter_at_end(struct deque_iter *iter) -{ - return d_empty(iter->target) || iter->end; -} -_Bool d_iter_to_start(struct deque_iter *iter) -{ - if (!d_empty(iter->target)) - { - iter->cursor = iter->target->front; - iter->index = 0; - iter->start = 1; - iter->end = 0; - return 1; - } - return 0; -} -_Bool d_iter_to_end(struct deque_iter *iter) -{ - if (!d_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 = 0; - iter->end = 1; - return 1; - } - return 0; -} -_Bool d_iter_next(struct deque_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = d_empty(iter->target); - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); - iter->index++; - return 1; -} -_Bool d_iter_prev(struct deque_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = d_empty(iter->target); - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; - iter->index--; - return 1; -} -_Bool d_iter_advance(struct deque_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - iter->start = d_empty(iter->target); - iter->index += steps; - iter->cursor = (iter->cursor + steps) % iter->target->capacity; - return 1; -} -_Bool d_iter_rewind(struct deque_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - iter->end = d_empty(iter->target); - iter->index -= steps; - if (iter->cursor < steps) - iter->cursor += iter->target->capacity; - iter->cursor -= steps; - return 1; -} -_Bool d_iter_go_to(struct deque_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return d_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return d_iter_advance(iter, index - iter->index); - return 1; -} -size_t d_iter_value(struct deque_iter *iter) -{ - if (d_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t *d_iter_rvalue(struct deque_iter *iter) -{ - if (d_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor]); -} -size_t d_iter_index(struct deque_iter *iter) -{ - return iter->index; -} -_Bool d_to_string(struct deque *_deque_, FILE *fptr) -{ - struct deque *d_ = _deque_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "front:%" - "I64u" - ", " - "back:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag, - d_->f_val, d_->alloc, (d_)->callbacks); -} -_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) - return 0; - i = (i + 1) % _deque_->capacity; - if (j + 1 < _deque_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/hashbidimap.c b/tests/src/cmc/hashbidimap.c deleted file mode 100644 index 1d853c5..0000000 --- a/tests/src/cmc/hashbidimap.c +++ /dev/null @@ -1,856 +0,0 @@ - -#include "cmc/hashbidimap.h" - -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_fval *f_val) -{ - return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); -} -struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hbm_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); - if (!_map_->buffer) - { - alloc->free(_map_->buffer); - alloc->free(_map_); - return ((void *)0); - } - _map_->count = 0; - _map_->capacity = real_capacity; - _map_->load = load; - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->flag = CMC_FLAG_OK; - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->it_start = hbm_impl_it_start; - _map_->it_end = hbm_impl_it_end; - return _map_; -} -void hbm_clear(struct hashbidimap *_map_) -{ - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashbidimap_entry *entry = _map_->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - if (_map_->f_key->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] = ((void *)0); - _map_->buffer[i][1] = ((void *)0); - } - _map_->count = 0; - _map_->flag = CMC_FLAG_OK; -} -void hbm_free(struct hashbidimap *_map_) -{ - hbm_clear(_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) -{ - ; - if (!alloc) - _map_->alloc = &cmc_alloc_node_default; - else - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->flag = CMC_FLAG_OK; -} -_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) -{ - if (hbm_full(_map_)) - { - 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)) - { - _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); - if (!key_entry || !val_entry) - { - if (key_entry) - *key_entry = ((void *)1); - if (val_entry) - *val_entry = ((void *)1); - _map_->alloc->free(entry); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - _map_->count++; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->create) - (_map_)->callbacks->create(); - ; - return 1; -} -_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) -{ - if (hbm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashbidimap_entry **key_entry, **val_entry; - val_entry = hbm_impl_get_entry_by_val(_map_, val); - if (!val_entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) - goto success; - if (hbm_impl_get_entry_by_key(_map_, new_key) != ((void *)0)) - { - _map_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - key_entry = (*val_entry)->ref[0]; - if (!key_entry || *key_entry != *val_entry) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashbidimap_entry *to_add = *key_entry; - size_t tmp_key = to_add->key; - to_add->key = new_key; - *key_entry = ((void *)1); - if (!hbm_impl_add_entry_to_key(_map_, to_add)) - { - to_add->key = tmp_key; - *key_entry = to_add; - _map_->flag = CMC_FLAG_ERROR; - return 0; - } -success: - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->update) - (_map_)->callbacks->update(); - ; - return 1; -} -_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) -{ - if (hbm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashbidimap_entry **key_entry, **val_entry; - key_entry = hbm_impl_get_entry_by_key(_map_, key); - if (!key_entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) - goto success; - if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) - { - _map_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - val_entry = (*key_entry)->ref[1]; - if (!val_entry || *val_entry != *key_entry) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashbidimap_entry *to_add = *val_entry; - size_t tmp_val = to_add->value; - to_add->value = new_val; - *val_entry = ((void *)1); - if (!hbm_impl_add_entry_to_val(_map_, to_add)) - { - to_add->value = tmp_val; - *val_entry = to_add; - _map_->flag = CMC_FLAG_ERROR; - return 0; - } -success: - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->update) - (_map_)->callbacks->update(); - ; - return 1; -} -_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val) -{ - if (hbm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashbidimap_entry **key_entry, **val_entry; - key_entry = hbm_impl_get_entry_by_key(_map_, key); - if (!key_entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - val_entry = (*key_entry)->ref[1]; - if (!val_entry || *val_entry != *key_entry) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - if (out_key) - *out_key = (*key_entry)->key; - if (out_val) - *out_val = (*key_entry)->value; - _map_->alloc->free(*key_entry); - *key_entry = ((void *)1); - *val_entry = ((void *)1); - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val) -{ - if (hbm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashbidimap_entry **key_entry, **val_entry; - val_entry = hbm_impl_get_entry_by_val(_map_, val); - if (!val_entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - key_entry = (*val_entry)->ref[0]; - if (!key_entry || *key_entry != *val_entry) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - if (out_key) - *out_key = (*val_entry)->key; - if (out_val) - *out_val = (*val_entry)->value; - _map_->alloc->free(*val_entry); - *key_entry = ((void *)1); - *val_entry = ((void *)1); - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -size_t hbm_get_key(struct hashbidimap *_map_, size_t val) -{ - struct hashbidimap_entry **entry = hbm_impl_get_entry_by_val(_map_, val); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return (*entry)->key; -} -size_t hbm_get_val(struct hashbidimap *_map_, size_t key) -{ - struct hashbidimap_entry **entry = hbm_impl_get_entry_by_key(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return (*entry)->value; -} -_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key) -{ - _map_->flag = CMC_FLAG_OK; - _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val) -{ - _map_->flag = CMC_FLAG_OK; - _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool hbm_empty(struct hashbidimap *_map_) -{ - return _map_->count == 0; -} -_Bool hbm_full(struct hashbidimap *_map_) -{ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; -} -size_t hbm_count(struct hashbidimap *_map_) -{ - return _map_->count; -} -size_t hbm_capacity(struct hashbidimap *_map_) -{ - return _map_->capacity; -} -double hbm_load(struct hashbidimap *_map_) -{ - return _map_->load; -} -int hbm_flag(struct hashbidimap *_map_) -{ - return _map_->flag; -} -_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) -{ - _map_->flag = CMC_FLAG_OK; - if (_map_->capacity == capacity) - goto success; - if (_map_->capacity > capacity / _map_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _map_->load) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t new_cap = hbm_impl_calculate_size(capacity); - if (new_cap < _map_->count / _map_->load) - { - _map_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashbidimap *_new_map_ = - hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); - if (!_new_map_) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = 0; i < _map_->capacity; i++) - { - 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); - if (!e1 || !e2) - { - _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; - _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; - _map_->alloc->free(_new_map_->buffer); - _map_->alloc->free(_new_map_); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - _new_map_->count++; - } - } - if (_map_->count != _new_map_->count) - { - _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; - _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; - _map_->alloc->free(_new_map_->buffer); - _map_->alloc->free(_new_map_); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashbidimap_entry *(*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 1; -} -struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) -{ - struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); - if (!result) - { - _map_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _map_->callbacks; - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashbidimap_entry *scan = _map_->buffer[i][0]; - if (scan && scan != ((void *)1)) - { - size_t tmp_key; - size_t 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; - 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++; - } - } - _map_->flag = CMC_FLAG_OK; - return result; -} -_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_) -{ - _map1_->flag = CMC_FLAG_OK; - _map2_->flag = CMC_FLAG_OK; - if (_map1_->count != _map2_->count) - return 0; - struct hashbidimap *_mapA_; - struct hashbidimap *_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 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); - if (!entry_B) - return 0; - if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) - return 0; - } - } - return 1; -} -struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target) -{ - struct hashbidimap_iter *iter = target->alloc->malloc(sizeof(struct hashbidimap_iter)); - if (!iter) - return ((void *)0); - hbm_iter_init(iter, target); - return iter; -} -void hbm_iter_free(struct hashbidimap_iter *iter) -{ - iter->target->alloc->free(iter); -} -void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target) -{ - memset(iter, 0, sizeof(struct hashbidimap_iter)); - iter->target = target; - iter->start = 1; - iter->end = hbm_empty(target); - if (!hbm_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - struct hashbidimap_entry *entry = target->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - iter->first = i; - break; - } - } - iter->cursor = iter->first; - for (size_t i = target->capacity; i > 0; i--) - { - struct hashbidimap_entry *entry = target->buffer[i - 1][0]; - if (entry && entry != ((void *)1)) - { - iter->last = i - 1; - break; - } - } - } -} -_Bool hbm_iter_start(struct hashbidimap_iter *iter) -{ - return hbm_empty(iter->target) || iter->start; -} -_Bool hbm_iter_end(struct hashbidimap_iter *iter) -{ - return hbm_empty(iter->target) || iter->end; -} -void hbm_iter_to_start(struct hashbidimap_iter *iter) -{ - if (!hbm_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = 0; - } -} -void hbm_iter_to_end(struct hashbidimap_iter *iter) -{ - if (!hbm_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = 0; - iter->end = 1; - } -} -_Bool hbm_iter_next(struct hashbidimap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = hbm_empty(iter->target); - struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; - iter->index++; - while (1) - { - iter->cursor++; - scan = iter->target->buffer[iter->cursor][0]; - if (scan != ((void *)0) && scan != ((void *)1)) - break; - } - return 1; -} -_Bool hbm_iter_prev(struct hashbidimap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = hbm_empty(iter->target); - struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; - iter->index--; - while (1) - { - iter->cursor--; - scan = iter->target->buffer[iter->cursor][0]; - if (scan != ((void *)0) && scan != ((void *)1)) - break; - } - return 1; -} -_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hbm_iter_next(iter); - return 1; -} -_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hbm_iter_prev(iter); - return 1; -} -_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hbm_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hbm_iter_advance(iter, index - iter->index); - return 1; -} -size_t hbm_iter_key(struct hashbidimap_iter *iter) -{ - if (hbm_empty(iter->target)) - { - iter->target->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - return iter->target->buffer[iter->cursor][0]->key; -} -size_t hbm_iter_value(struct hashbidimap_iter *iter) -{ - if (hbm_empty(iter->target)) - { - iter->target->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - return iter->target->buffer[iter->cursor][0]->value; -} -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) -{ - struct hashbidimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashbidimap_entry)); - if (!entry) - return ((void *)0); - entry->key = key; - entry->value = value; - entry->dist[0] = 0; - entry->dist[1] = 0; - entry->ref[0] = ((void *)0); - entry->ref[1] = ((void *)0); - return entry; -} -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; - struct hashbidimap_entry *target = _map_->buffer[pos][0]; - while (target != ((void *)0)) - { - if (target != ((void *)1) && _map_->f_key->cmp(target->key, key) == 0) - return &(_map_->buffer[pos % _map_->capacity][0]); - pos++; - target = _map_->buffer[pos % _map_->capacity][0]; - } - return ((void *)0); -} -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; - struct hashbidimap_entry *target = _map_->buffer[pos][1]; - while (target != ((void *)0)) - { - if (target != ((void *)1) && _map_->f_val->cmp(target->value, val) == 0) - return &(_map_->buffer[pos % _map_->capacity][1]); - pos++; - target = _map_->buffer[pos % _map_->capacity][1]; - } - return ((void *)0); -} -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]); - if (*scan == ((void *)0)) - { - *scan = entry; - entry->ref[0] = scan; - return scan; - } - else - { - while (1) - { - pos++; - scan = &(_map_->buffer[pos % _map_->capacity][0]); - if (*scan == ((void *)0) || *scan == ((void *)1)) - { - 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 hashbidimap_entry *_tmp_ = *scan; - *scan = entry; - entry = _tmp_; - } - } - } - return ((void *)0); -} -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]); - if (*scan == ((void *)0)) - { - *scan = entry; - entry->ref[1] = scan; - return scan; - } - else - { - while (1) - { - pos++; - scan = &(_map_->buffer[pos % _map_->capacity][1]); - if (*scan == ((void *)0) || *scan == ((void *)1)) - { - 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 hashbidimap_entry *_tmp_ = *scan; - *scan = entry; - entry = _tmp_; - } - } - } - return ((void *)0); -} -static size_t hbm_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 hashbidimap_iter hbm_impl_it_start(struct hashbidimap *_map_) -{ - struct hashbidimap_iter iter; - hbm_iter_init(&iter, _map_); - return iter; -} -static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_) -{ - struct hashbidimap_iter iter; - hbm_iter_init(&iter, _map_); - hbm_iter_to_end(&iter); - return iter; -} -_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr) -{ - struct hashbidimap *m_ = _map_; - return 0 <= fprintf(fptr, - "struct %s<%s, %s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_key:%p, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); -} -_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep) -{ - fprintf(fptr, "%s", start); - size_t last = 0; - for (size_t i = _map_->capacity; i > 0; i--) - { - struct hashbidimap_entry *entry = _map_->buffer[i - 1][0]; - if (entry && entry != ((void *)1)) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashbidimap_entry *entry = _map_->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - if (!_map_->f_key->str(fptr, entry->key)) - return 0; - fprintf(fptr, "%s", key_val_sep); - if (!_map_->f_val->str(fptr, entry->value)) - return 0; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/hashmap.c b/tests/src/cmc/hashmap.c deleted file mode 100644 index abb8bf0..0000000 --- a/tests/src/cmc/hashmap.c +++ /dev/null @@ -1,788 +0,0 @@ - -#include "cmc/hashmap.h" - -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) -{ - 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) -{ - ; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hm_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct hashmap *_map_ = alloc->malloc(sizeof(struct hashmap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); - if (!_map_->buffer) - { - alloc->free(_map_); - return ((void *)0); - } - _map_->count = 0; - _map_->capacity = real_capacity; - _map_->load = load; - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - return _map_; -} -void hm_clear(struct hashmap *_map_) -{ - if (_map_->f_key->free || _map_->f_val->free) - { - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmap_entry *entry = &(_map_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (_map_->f_key->free) - _map_->f_key->free(entry->key); - if (_map_->f_val->free) - _map_->f_val->free(entry->value); - } - } - } - memset(_map_->buffer, 0, sizeof(struct hashmap_entry) * _map_->capacity); - _map_->count = 0; - _map_->flag = CMC_FLAG_OK; -} -void hm_free(struct hashmap *_map_) -{ - if (_map_->f_key->free || _map_->f_val->free) - { - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmap_entry *entry = &(_map_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (_map_->f_key->free) - _map_->f_key->free(entry->key); - if (_map_->f_val->free) - _map_->f_val->free(entry->value); - } - } - } - _map_->alloc->free(_map_->buffer); - _map_->alloc->free(_map_); -} -void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _map_->alloc = &cmc_alloc_node_default; - else - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->flag = CMC_FLAG_OK; -} -_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) -{ - if (hm_full(_map_)) - { - if (!hm_resize(_map_, _map_->capacity + 1)) - return 0; - } - if (hm_impl_get_entry(_map_, key) != ((void *)0)) - { - _map_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - size_t hash = _map_->f_key->hash(key); - size_t original_pos = hash % _map_->capacity; - size_t pos = original_pos; - struct hashmap_entry *target = &(_map_->buffer[pos]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->key = key; - target->value = value; - target->dist = 0; - target->state = CMC_ES_FILLED; - } - else - { - while (1) - { - 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) - { - size_t tmp_k = target->key; - size_t 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 1; -} -_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - 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 1; -} -_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmap_entry *result = hm_impl_get_entry(_map_, key); - if (result == ((void *)0)) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (out_value) - *out_value = result->value; - result->key = (size_t){ 0 }; - result->value = (size_t){ 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 1; -} -_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t max_key = (size_t){ 0 }; - size_t max_val = (size_t){ 0 }; - for (size_t i = 0; i < _map_->capacity; i++) - { - if (_map_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - max_key = _map_->buffer[i].key; - max_val = _map_->buffer[i].value; - first = 0; - } - else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) - { - max_key = _map_->buffer[i].key; - max_val = _map_->buffer[i].value; - } - } - } - if (key) - *key = max_key; - if (value) - *value = max_val; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return 1; -} -_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t min_key = (size_t){ 0 }; - size_t min_val = (size_t){ 0 }; - for (size_t i = 0; i < _map_->capacity; i++) - { - if (_map_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - min_key = _map_->buffer[i].key; - min_val = _map_->buffer[i].value; - first = 0; - } - else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) - { - min_key = _map_->buffer[i].key; - min_val = _map_->buffer[i].value; - } - } - } - if (key) - *key = min_key; - if (value) - *value = min_val; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return 1; -} -size_t hm_get(struct hashmap *_map_, size_t key) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return entry->value; -} -size_t *hm_get_ref(struct hashmap *_map_, size_t key) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return ((void *)0); - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return &(entry->value); -} -_Bool hm_contains(struct hashmap *_map_, size_t key) -{ - _map_->flag = CMC_FLAG_OK; - _Bool result = hm_impl_get_entry(_map_, key) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool hm_empty(struct hashmap *_map_) -{ - return _map_->count == 0; -} -_Bool hm_full(struct hashmap *_map_) -{ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; -} -size_t hm_count(struct hashmap *_map_) -{ - return _map_->count; -} -size_t hm_capacity(struct hashmap *_map_) -{ - return _map_->capacity; -} -double hm_load(struct hashmap *_map_) -{ - return _map_->load; -} -int hm_flag(struct hashmap *_map_) -{ - return _map_->flag; -} -_Bool hm_resize(struct hashmap *_map_, size_t capacity) -{ - _map_->flag = CMC_FLAG_OK; - if (_map_->capacity == capacity) - goto success; - if (_map_->capacity > capacity / _map_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _map_->load) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t theoretical_size = hm_impl_calculate_size(capacity); - if (theoretical_size < _map_->count / _map_->load) - { - _map_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashmap *_new_map_ = - hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); - if (!_new_map_) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = 0; i < _map_->capacity; i++) - { - if (_map_->buffer[i].state == CMC_ES_FILLED) - { - size_t key = _map_->buffer[i].key; - size_t value = _map_->buffer[i].value; - hm_insert(_new_map_, key, value); - } - } - if (_map_->count != _new_map_->count) - { - hm_free(_new_map_); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashmap_entry *tmp_b = _map_->buffer; - _map_->buffer = _new_map_->buffer; - _new_map_->buffer = tmp_b; - size_t tmp_c = _map_->capacity; - _map_->capacity = _new_map_->capacity; - _new_map_->capacity = tmp_c; - _new_map_->f_key = &(struct hashmap_fkey){ ((void *)0) }; - _new_map_->f_val = &(struct hashmap_fval){ ((void *)0) }; - hm_free(_new_map_); -success: - if ((_map_)->callbacks && (_map_)->callbacks->resize) - (_map_)->callbacks->resize(); - ; - return 1; -} -struct hashmap *hm_copy_of(struct hashmap *_map_) -{ - struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); - if (!result) - { - _map_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _map_->callbacks; - if (_map_->f_key->cpy || _map_->f_val->cpy) - { - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmap_entry *scan = &(_map_->buffer[i]); - if (scan->state != CMC_ES_EMPTY) - { - struct hashmap_entry *target = &(result->buffer[i]); - if (scan->state == CMC_ES_DELETED) - target->state = CMC_ES_DELETED; - else - { - target->state = scan->state; - target->dist = scan->dist; - if (_map_->f_key->cpy) - target->key = _map_->f_key->cpy(scan->key); - else - target->key = scan->key; - if (_map_->f_val->cpy) - target->value = _map_->f_val->cpy(scan->value); - else - target->value = scan->value; - } - } - } - } - else - memcpy(result->buffer, _map_->buffer, sizeof(struct hashmap_entry) * _map_->capacity); - result->count = _map_->count; - _map_->flag = CMC_FLAG_OK; - return result; -} -_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_) -{ - _map1_->flag = CMC_FLAG_OK; - _map2_->flag = CMC_FLAG_OK; - if (_map1_->count != _map2_->count) - return 0; - struct hashmap *_map_a_; - struct hashmap *_map_b_; - _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; - _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; - for (size_t i = 0; i < _map_a_->capacity; i++) - { - if (_map_a_->buffer[i].state == CMC_ES_FILLED) - { - struct hashmap_entry *entry_a = &(_map_a_->buffer[i]); - struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key); - if (!entry_b) - return 0; - if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) - return 0; - } - } - return 1; -} -static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - size_t pos = hash % _map_->capacity; - struct hashmap_entry *target = &(_map_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) - { - if (_map_->f_key->cmp(target->key, key) == 0) - return target; - pos++; - target = &(_map_->buffer[pos % _map_->capacity]); - } - return ((void *)0); -} -static size_t hm_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) -{ - return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); -} -struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - struct hashmap _map_ = { 0 }; - if (capacity == 0 || load <= 0 || load >= 1) - return _map_; - if (capacity >= 0xffffffffffffffffULL * load) - return _map_; - if (!f_key || !f_val) - return _map_; - size_t real_capacity = hm_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); - if (!_map_.buffer) - return _map_; - _map_.count = 0; - _map_.capacity = real_capacity; - _map_.load = load; - _map_.flag = CMC_FLAG_OK; - _map_.f_key = f_key; - _map_.f_val = f_val; - _map_.alloc = alloc; - (&_map_)->callbacks = callbacks; - return _map_; -} -void hm_release(struct hashmap _map_) -{ - if (_map_.f_key->free || _map_.f_val->free) - { - for (size_t i = 0; i < _map_.capacity; i++) - { - struct hashmap_entry *entry = &(_map_.buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (_map_.f_key->free) - _map_.f_key->free(entry->key); - if (_map_.f_val->free) - _map_.f_val->free(entry->value); - } - } - } - _map_.alloc->free(_map_.buffer); -} -struct hashmap_iter hm_iter_start(struct hashmap *target) -{ - struct hashmap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = 1; - iter.end = hm_empty(target); - if (!hm_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 hashmap_iter hm_iter_end(struct hashmap *target) -{ - struct hashmap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = hm_empty(target); - iter.end = 1; - if (!hm_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 hm_iter_at_start(struct hashmap_iter *iter) -{ - return hm_empty(iter->target) || iter->start; -} -_Bool hm_iter_at_end(struct hashmap_iter *iter) -{ - return hm_empty(iter->target) || iter->end; -} -_Bool hm_iter_to_start(struct hashmap_iter *iter) -{ - if (!hm_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = hm_empty(iter->target); - return 1; - } - return 0; -} -_Bool hm_iter_to_end(struct hashmap_iter *iter) -{ - if (!hm_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = hm_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool hm_iter_next(struct hashmap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = hm_empty(iter->target); - struct hashmap_entry *scan = &(iter->target->buffer[iter->cursor]); - iter->index++; - while (1) - { - iter->cursor++; - scan = &(iter->target->buffer[iter->cursor]); - if (scan->state == CMC_ES_FILLED) - break; - } - return 1; -} -_Bool hm_iter_prev(struct hashmap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = hm_empty(iter->target); - struct hashmap_entry *scan = &(iter->target->buffer[iter->cursor]); - iter->index--; - while (1) - { - iter->cursor--; - scan = &(iter->target->buffer[iter->cursor]); - if (scan->state == CMC_ES_FILLED) - break; - } - return 1; -} -_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hm_iter_next(iter); - return 1; -} -_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hm_iter_prev(iter); - return 1; -} -_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hm_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hm_iter_advance(iter, index - iter->index); - return 1; -} -size_t hm_iter_key(struct hashmap_iter *iter) -{ - if (hm_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor].key; -} -size_t hm_iter_value(struct hashmap_iter *iter) -{ - if (hm_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor].value; -} -size_t *hm_iter_rvalue(struct hashmap_iter *iter) -{ - if (hm_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor].value); -} -size_t hm_iter_index(struct hashmap_iter *iter) -{ - return iter->index; -} -_Bool hm_to_string(struct hashmap *_map_, FILE *fptr) -{ - struct hashmap *m_ = _map_; - return 0 <= fprintf(fptr, - "struct %s<%s, %s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_key:%p, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); -} -_Bool hm_print(struct hashmap *_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 hashmap_entry *entry = &(_map_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (!_map_->f_key->str(fptr, entry->key)) - return 0; - fprintf(fptr, "%s", key_val_sep); - if (!_map_->f_val->str(fptr, entry->value)) - return 0; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/hashmultimap.c b/tests/src/cmc/hashmultimap.c deleted file mode 100644 index f99130c..0000000 --- a/tests/src/cmc/hashmultimap.c +++ /dev/null @@ -1,931 +0,0 @@ - -#include "cmc/hashmultimap.h" - -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_fval *f_val) -{ - return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); -} -struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - size_t real_capacity = hmm_impl_calculate_size(capacity / load); - struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); - if (!_map_->buffer) - { - alloc->free(_map_); - return ((void *)0); - } - _map_->count = 0; - _map_->capacity = real_capacity; - _map_->load = load; - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - return _map_; -} -void hmm_clear(struct hashmultimap *_map_) -{ - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - struct hashmultimap_entry *next = scan->next; - if (_map_->f_key->free) - _map_->f_key->free(scan->key); - if (_map_->f_val->free) - _map_->f_val->free(scan->value); - _map_->alloc->free(scan); - scan = next; - } - } - memset(_map_->buffer, 0, sizeof(struct hashmultimap_entry *[2]) * _map_->capacity); - _map_->count = 0; - _map_->flag = CMC_FLAG_OK; -} -void hmm_free(struct hashmultimap *_map_) -{ - size_t index = 0; - while (index < _map_->capacity) - { - struct hashmultimap_entry *scan = _map_->buffer[index][0]; - if (scan) - { - if (scan->next == ((void *)0) && scan->prev == ((void *)0)) - { - 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) - { - struct hashmultimap_entry *tmp = scan; - scan = scan->next; - if (_map_->f_key->free) - _map_->f_key->free(tmp->key); - if (_map_->f_val->free) - _map_->f_val->free(tmp->value); - _map_->alloc->free(tmp); - } - } - } - index++; - } - _map_->alloc->free(_map_->buffer); - _map_->alloc->free(_map_); -} -void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _map_->alloc = &cmc_alloc_node_default; - else - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->flag = CMC_FLAG_OK; -} -_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) -{ - if (hmm_full(_map_)) - { - if (!hmm_resize(_map_, _map_->capacity + 1)) - return 0; - } - size_t hash = _map_->f_key->hash(key); - size_t pos = hash % _map_->capacity; - struct hashmultimap_entry *entry = hmm_impl_new_entry(_map_, key, value); - if (_map_->buffer[pos][0] == ((void *)0)) - { - _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 1; -} -_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - 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 1; -} -size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - if (entry == ((void *)0)) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (old_values) - { - size_t total = hmm_impl_key_count(_map_, key); - if (total == 0) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - *old_values = _map_->alloc->malloc(sizeof(size_t) * total); - if (!(*old_values)) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - } - size_t index = 0; - while (entry) - { - 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 hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - 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]); - if (*head == ((void *)0)) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - struct hashmultimap_entry *entry = *head; - if (entry->next == ((void *)0) && entry->prev == ((void *)0)) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - { - *head = ((void *)0); - *tail = ((void *)0); - if (out_value) - *out_value = entry->value; - } - else - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - } - else - { - _Bool found = 0; - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - { - if (*head == entry) - *head = entry->next; - if (*tail == entry) - *tail = entry->prev; - if (entry->prev) - entry->prev->next = entry->next; - if (entry->next) - entry->next->prev = entry->prev; - if (out_value) - *out_value = entry->value; - found = 1; - break; - } - else - entry = entry->next; - } - if (!found) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - } - _map_->alloc->free(entry); - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - 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]); - if (*head == ((void *)0)) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (out_values) - { - size_t total = hmm_impl_key_count(_map_, key); - if (total == 0) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - *out_values = _map_->alloc->malloc(sizeof(size_t) * total); - if (!(*out_values)) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - } - size_t index = 0; - struct hashmultimap_entry *entry = *head; - if (entry->next == ((void *)0)) - { - *head = ((void *)0); - *tail = ((void *)0); - if (out_values) - (*out_values)[index] = entry->value; - index++; - _map_->alloc->free(entry); - } - else - { - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - { - if (*head == entry) - *head = entry->next; - if (*tail == entry) - *tail = entry->prev; - struct hashmultimap_entry *next = entry->next; - if (entry->prev) - entry->prev->next = entry->next; - if (entry->next) - 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 hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t max_key = (size_t){ 0 }; - size_t max_val = (size_t){ 0 }; - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - if (first) - { - max_key = scan->key; - max_val = scan->value; - first = 0; - } - else if (_map_->f_key->cmp(scan->key, max_key) > 0) - { - max_key = scan->key; - max_val = scan->value; - } - scan = scan->next; - } - } - 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 1; -} -_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t min_key = (size_t){ 0 }; - size_t min_val = (size_t){ 0 }; - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - if (first) - { - min_key = scan->key; - min_val = scan->value; - first = 0; - } - else if (_map_->f_key->cmp(scan->key, min_key) < 0) - { - min_key = scan->key; - min_val = scan->value; - } - scan = scan->next; - } - } - 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 1; -} -size_t hmm_get(struct hashmultimap *_map_, size_t key) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return entry->value; -} -size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return ((void *)0); - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return &(entry->value); -} -_Bool hmm_contains(struct hashmultimap *_map_, size_t key) -{ - _map_->flag = CMC_FLAG_OK; - _Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool hmm_empty(struct hashmultimap *_map_) -{ - return _map_->count == 0; -} -_Bool hmm_full(struct hashmultimap *_map_) -{ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; -} -size_t hmm_count(struct hashmultimap *_map_) -{ - return _map_->count; -} -size_t hmm_key_count(struct hashmultimap *_map_, size_t key) -{ - return hmm_impl_key_count(_map_, key); -} -size_t hmm_capacity(struct hashmultimap *_map_) -{ - return _map_->capacity; -} -double hmm_load(struct hashmultimap *_map_) -{ - return _map_->load; -} -int hmm_flag(struct hashmultimap *_map_) -{ - return _map_->flag; -} -_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) -{ - _map_->flag = CMC_FLAG_OK; - if (_map_->capacity == capacity) - goto success; - if (_map_->capacity > capacity / _map_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _map_->load) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t theoretical_size = hmm_impl_calculate_size(capacity); - if (theoretical_size < _map_->count / _map_->load) - { - _map_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashmultimap *_new_map_ = - hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); - if (!_new_map_) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - hmm_insert(_new_map_, scan->key, scan->value); - scan = scan->next; - } - } - if (_map_->count != _new_map_->count) - { - hmm_free(_new_map_); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashmultimap_entry *(*tmp_b)[2] = _map_->buffer; - _map_->buffer = _new_map_->buffer; - _new_map_->buffer = tmp_b; - size_t tmp_c = _map_->capacity; - _map_->capacity = _new_map_->capacity; - _new_map_->capacity = tmp_c; - _new_map_->f_key = &(struct hashmultimap_fkey){ ((void *)0) }; - _new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) }; - hmm_free(_new_map_); -success: - if ((_map_)->callbacks && (_map_)->callbacks->resize) - (_map_)->callbacks->resize(); - ; - return 1; -} -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)); - if (!result) - { - _map_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - size_t key; - size_t value; - if (_map_->f_key->cpy) - key = _map_->f_key->cpy(scan->key); - else - key = scan->key; - if (_map_->f_val->cpy) - value = _map_->f_val->cpy(scan->value); - else - value = scan->value; - hmm_insert(result, key, value); - scan = scan->next; - } - } - (result)->callbacks = _map_->callbacks; - _map_->flag = CMC_FLAG_OK; - return result; -} -_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_) -{ - _map1_->flag = CMC_FLAG_OK; - _map2_->flag = CMC_FLAG_OK; - if (_map1_->count != _map2_->count) - return 0; - struct hashmultimap *_map_a_; - struct hashmultimap *_map_b_; - _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; - _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; - for (size_t i = 0; i < _map_a_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_a_->buffer[i][0]; - while (scan) - { - if (hmm_impl_key_count(_map_a_, scan->key) != hmm_impl_key_count(_map_b_, scan->key)) - return 0; - scan = scan->next; - } - } - return 1; -} -struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value) -{ - struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); - if (!entry) - return ((void *)0); - entry->key = key; - entry->value = value; - entry->next = ((void *)0); - entry->prev = ((void *)0); - return entry; -} -struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - return entry; - entry = entry->next; - } - return ((void *)0); -} -size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - size_t total_count = 0; - if (!entry) - return total_count; - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - total_count++; - entry = entry->next; - } - return total_count; -} -size_t hmm_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) -{ - struct hashmultimap_iter iter; - iter.target = target; - iter.curr_entry = ((void *)0); - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = 1; - iter.end = hmm_empty(target); - if (!hmm_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - struct hashmultimap_entry *entry = target->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - 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 hashmultimap_entry *entry = target->buffer[i - 1][1]; - if (entry && entry != ((void *)1)) - { - iter.last = i - 1; - break; - } - } - } - return iter; -} -struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target) -{ - struct hashmultimap_iter iter; - iter.target = target; - iter.curr_entry = ((void *)0); - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = hmm_empty(target); - iter.end = 1; - if (!hmm_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - struct hashmultimap_entry *entry = target->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - iter.first = i; - break; - } - } - for (size_t i = target->capacity; i > 0; i--) - { - struct hashmultimap_entry *entry = target->buffer[i - 1][1]; - if (entry && entry != ((void *)1)) - { - iter.curr_entry = target->buffer[i - 1][1]; - iter.last = i - 1; - break; - } - } - iter.cursor = iter.last; - iter.index = target->count - 1; - } - return iter; -} -_Bool hmm_iter_at_start(struct hashmultimap_iter *iter) -{ - return hmm_empty(iter->target) || iter->start; -} -_Bool hmm_iter_at_end(struct hashmultimap_iter *iter) -{ - return hmm_empty(iter->target) || iter->end; -} -_Bool hmm_iter_to_start(struct hashmultimap_iter *iter) -{ - if (!hmm_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = hmm_empty(iter->target); - iter->curr_entry = iter->target->buffer[iter->first][0]; - return 1; - } - return 0; -} -_Bool hmm_iter_to_end(struct hashmultimap_iter *iter) -{ - if (!hmm_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = hmm_empty(iter->target); - iter->end = 1; - iter->curr_entry = iter->target->buffer[iter->last][1]; - return 1; - } - return 0; -} -_Bool hmm_iter_next(struct hashmultimap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->curr_entry->next != ((void *)0)) - { - iter->curr_entry = iter->curr_entry->next; - iter->index++; - } - else - { - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - iter->cursor++; - while (iter->target->buffer[iter->cursor][0] == ((void *)0)) - iter->cursor++; - iter->curr_entry = iter->target->buffer[iter->cursor][0]; - iter->index++; - } - iter->start = hmm_empty(iter->target); - return 1; -} -_Bool hmm_iter_prev(struct hashmultimap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->curr_entry->prev != ((void *)0)) - { - iter->curr_entry = iter->curr_entry->prev; - iter->index--; - } - else - { - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - iter->cursor--; - while (iter->target->buffer[iter->cursor][1] == ((void *)0)) - iter->cursor--; - iter->curr_entry = iter->target->buffer[iter->cursor][1]; - iter->index--; - } - iter->end = hmm_empty(iter->target); - return 1; -} -_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hmm_iter_next(iter); - return 1; -} -_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hmm_iter_prev(iter); - return 1; -} -_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hmm_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hmm_iter_advance(iter, index - iter->index); - return 1; -} -size_t hmm_iter_key(struct hashmultimap_iter *iter) -{ - if (hmm_empty(iter->target)) - return (size_t){ 0 }; - return iter->curr_entry->key; -} -size_t hmm_iter_value(struct hashmultimap_iter *iter) -{ - if (hmm_empty(iter->target)) - return (size_t){ 0 }; - return iter->curr_entry->value; -} -size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter) -{ - if (hmm_empty(iter->target)) - return ((void *)0); - return &(iter->curr_entry->value); -} -size_t hmm_iter_index(struct hashmultimap_iter *iter) -{ - return iter->index; -} -_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr) -{ - struct hashmultimap *m_ = _map_; - return 0 <= fprintf(fptr, - "struct %s<%s, %s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_key:%p, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); -} -_Bool hmm_print(struct hashmultimap *_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 hashmultimap_entry *entry = _map_->buffer[i - 1][1]; - if (entry && entry != ((void *)1)) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan != ((void *)0)) - { - if (!_map_->f_key->str(fptr, scan->key)) - return 0; - fprintf(fptr, "%s", key_val_sep); - if (!_map_->f_val->str(fptr, scan->value)) - return 0; - scan = scan->next; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/hashmultiset.c b/tests/src/cmc/hashmultiset.c deleted file mode 100644 index 64d656a..0000000 --- a/tests/src/cmc/hashmultiset.c +++ /dev/null @@ -1,972 +0,0 @@ - -#include "cmc/hashmultiset.h" - -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) -{ - return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); -} -struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_val) - return ((void *)0); - size_t real_capacity = hms_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); - if (!_set_) - return ((void *)0); - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); - if (!_set_->buffer) - { - alloc->free(_set_); - return ((void *)0); - } - _set_->count = 0; - _set_->cardinality = 0; - _set_->capacity = real_capacity; - _set_->load = load; - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - return _set_; -} -void hms_clear(struct hashmultiset *_set_) -{ - if (_set_->f_val->free) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - _set_->f_val->free(entry->value); - } - } - } - memset(_set_->buffer, 0, sizeof(struct hashmultiset_entry) * _set_->capacity); - _set_->count = 0; - _set_->flag = CMC_FLAG_OK; -} -void hms_free(struct hashmultiset *_set_) -{ - if (_set_->f_val->free) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *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 hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _set_->alloc = &cmc_alloc_node_default; - else - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - _set_->flag = CMC_FLAG_OK; -} -_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); - if (!entry) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - if (!new_node) - entry->multiplicity++; - _set_->cardinality++; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->create) - (_set_)->callbacks->create(); - ; - return 1; -} -_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); - if (!entry) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - 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 1; -} -_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) -{ - if (multiplicity == 0) - { - struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); - if (!result) - goto success; - _set_->count--; - _set_->cardinality -= result->multiplicity; - result->value = (size_t){ 0 }; - result->multiplicity = 0; - result->dist = 0; - result->state = CMC_ES_DELETED; - goto success; - } - _Bool 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; - entry->multiplicity = multiplicity; -success: - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->update) - (_set_)->callbacks->update(); - ; - return 1; -} -_Bool hms_remove(struct hashmultiset *_set_, size_t value) -{ - if (hms_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); - if (!result) - { - _set_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (result->multiplicity > 1) - result->multiplicity--; - else - { - result->value = (size_t){ 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 1; -} -size_t hms_remove_all(struct hashmultiset *_set_, size_t value) -{ - if (hms_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); - if (!result) - { - _set_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - size_t removed = result->multiplicity; - result->value = (size_t){ 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 hms_max(struct hashmultiset *_set_, size_t *value) -{ - if (hms_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t max_val = (size_t){ 0 }; - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - max_val = _set_->buffer[i].value; - first = 0; - } - else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) - { - max_val = _set_->buffer[i].value; - } - } - } - if (value) - *value = max_val; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool hms_min(struct hashmultiset *_set_, size_t *value) -{ - if (hms_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t min_val = (size_t){ 0 }; - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - min_val = _set_->buffer[i].value; - first = 0; - } - else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) - { - min_val = _set_->buffer[i].value; - } - } - } - if (value) - *value = min_val; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value) -{ - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - if (!entry) - return 0; - return entry->multiplicity; -} -_Bool hms_contains(struct hashmultiset *_set_, size_t value) -{ - _set_->flag = CMC_FLAG_OK; - _Bool result = hms_impl_get_entry(_set_, value) != ((void *)0); - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return result; -} -_Bool hms_empty(struct hashmultiset *_set_) -{ - return _set_->count == 0; -} -_Bool hms_full(struct hashmultiset *_set_) -{ - return (double)_set_->capacity * _set_->load <= (double)_set_->count; -} -size_t hms_count(struct hashmultiset *_set_) -{ - return _set_->count; -} -size_t hms_cardinality(struct hashmultiset *_set_) -{ - return _set_->cardinality; -} -size_t hms_capacity(struct hashmultiset *_set_) -{ - return _set_->capacity; -} -double hms_load(struct hashmultiset *_set_) -{ - return _set_->load; -} -int hms_flag(struct hashmultiset *_set_) -{ - return _set_->flag; -} -_Bool hms_resize(struct hashmultiset *_set_, size_t capacity) -{ - _set_->flag = CMC_FLAG_OK; - if (_set_->capacity == capacity) - goto success; - if (_set_->capacity > capacity / _set_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _set_->load) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t theoretical_size = hms_impl_calculate_size(capacity); - if (theoretical_size < _set_->count / _set_->load) - { - _set_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashmultiset *_new_set_ = hms_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); - if (!_new_set_) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - size_t value = _set_->buffer[i].value; - size_t multiplicity = _set_->buffer[i].multiplicity; - struct hashmultiset_entry *entry = hms_impl_insert_and_return(_new_set_, value, ((void *)0)); - entry->multiplicity = multiplicity; - } - } - if (_set_->count != _new_set_->count) - { - hms_free(_new_set_); - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashmultiset_entry *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; - _new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) }; - hms_free(_new_set_); -success: - if ((_set_)->callbacks && (_set_)->callbacks->resize) - (_set_)->callbacks->resize(); - ; - return 1; -} -struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) -{ - struct hashmultiset *result = - hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); - if (!result) - { - _set_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _set_->callbacks; - if (_set_->f_val->cpy) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *scan = &(_set_->buffer[i]); - if (scan->state != CMC_ES_EMPTY) - { - struct hashmultiset_entry *target = &(result->buffer[i]); - if (scan->state == CMC_ES_DELETED) - target->state = CMC_ES_DELETED; - else - { - target->state = scan->state; - target->dist = scan->dist; - target->multiplicity = scan->multiplicity; - target->value = _set_->f_val->cpy(scan->value); - } - } - } - } - else - memcpy(result->buffer, _set_->buffer, sizeof(struct hashmultiset_entry) * _set_->capacity); - result->count = _set_->count; - result->cardinality = _set_->cardinality; - _set_->flag = CMC_FLAG_OK; - return result; -} -_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count != _set2_->count) - return 0; - if (_set1_->cardinality != _set2_->cardinality) - return 0; - if (_set1_->count == 0) - return 1; - struct hashmultiset *_set_a_; - struct hashmultiset *_set_b_; - _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; - _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; - for (size_t i = 0; i < _set_a_->capacity; i++) - { - if (_set_a_->buffer[i].state == CMC_ES_FILLED) - { - struct hashmultiset_entry *entry_a = &(_set_a_->buffer[i]); - struct hashmultiset_entry *entry_b = hms_impl_get_entry(_set_b_, entry_a->value); - if (!entry_b) - return 0; - if (entry_a->multiplicity != entry_b->multiplicity) - return 0; - } - } - return 1; -} -static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) -{ - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - if (!entry) - return 0; - return entry->multiplicity; -} -static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) -{ - if (new_node) - *new_node = 0; - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - if (entry != ((void *)0)) - return entry; - if (new_node) - *new_node = 1; - if (hms_full(_set_)) - { - if (!hms_resize(_set_, _set_->capacity + 1)) - return ((void *)0); - } - size_t hash = _set_->f_val->hash(value); - size_t original_pos = hash % _set_->capacity; - size_t pos = original_pos; - size_t curr_mul = 1; - struct hashmultiset_entry *target = &(_set_->buffer[pos]); - struct hashmultiset_entry *to_return = ((void *)0); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->value = value; - target->multiplicity = curr_mul; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - to_return = target; - } - else - { - while (1) - { - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->value = value; - target->multiplicity = curr_mul; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - if (!to_return) - to_return = target; - break; - } - else if (target->dist < pos - original_pos) - { - size_t tmp = target->value; - size_t tmp_dist = target->dist; - size_t tmp_mul = target->multiplicity; - target->value = value; - target->dist = pos - original_pos; - target->multiplicity = curr_mul; - value = tmp; - original_pos = pos - tmp_dist; - curr_mul = tmp_mul; - if (!to_return) - to_return = target; - } - } - } - _set_->count++; - return to_return; -} -static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value) -{ - size_t hash = _set_->f_val->hash(value); - size_t pos = hash % _set_->capacity; - struct hashmultiset_entry *target = &(_set_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) - { - if (_set_->f_val->cmp(target->value, value) == 0) - return target; - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); - } - return ((void *)0); -} -static size_t hms_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -struct hashmultiset_iter hms_iter_start(struct hashmultiset *target) -{ - struct hashmultiset_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = 1; - iter.end = hms_empty(target); - if (!hms_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 hashmultiset_iter hms_iter_end(struct hashmultiset *target) -{ - struct hashmultiset_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = hms_empty(target); - iter.end = 1; - if (!hms_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 hms_iter_at_start(struct hashmultiset_iter *iter) -{ - return hms_empty(iter->target) || iter->start; -} -_Bool hms_iter_at_end(struct hashmultiset_iter *iter) -{ - return hms_empty(iter->target) || iter->end; -} -_Bool hms_iter_to_start(struct hashmultiset_iter *iter) -{ - if (!hms_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = hms_empty(iter->target); - return 1; - } - return 0; -} -_Bool hms_iter_to_end(struct hashmultiset_iter *iter) -{ - if (!hms_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = hms_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool hms_iter_next(struct hashmultiset_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = hms_empty(iter->target); - struct hashmultiset_entry *scan = &(iter->target->buffer[iter->cursor]); - iter->index++; - while (1) - { - iter->cursor++; - scan = &(iter->target->buffer[iter->cursor]); - if (scan->state == CMC_ES_FILLED) - break; - } - return 1; -} -_Bool hms_iter_prev(struct hashmultiset_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = hms_empty(iter->target); - struct hashmultiset_entry *scan = &(iter->target->buffer[iter->cursor]); - iter->index--; - while (1) - { - iter->cursor--; - scan = &(iter->target->buffer[iter->cursor]); - if (scan->state == CMC_ES_FILLED) - break; - } - return 1; -} -_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hms_iter_next(iter); - return 1; -} -_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hms_iter_prev(iter); - return 1; -} -_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hms_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hms_iter_advance(iter, index - iter->index); - return 1; -} -size_t hms_iter_value(struct hashmultiset_iter *iter) -{ - if (hms_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor].value; -} -size_t hms_iter_multiplicity(struct hashmultiset_iter *iter) -{ - if (hms_empty(iter->target)) - return 0; - return iter->target->buffer[iter->cursor].multiplicity; -} -size_t hms_iter_index(struct hashmultiset_iter *iter) -{ - return iter->index; -} -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)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - size_t value = hms_iter_value(&iter1); - size_t m1 = hms_iter_multiplicity(&iter1); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - size_t max_ = m1 > m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - size_t value = hms_iter_value(&iter2); - size_t m1 = hms_impl_multiplicity_of(_set1_, value); - size_t m2 = hms_iter_multiplicity(&iter2); - size_t max_ = m1 > m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *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)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct hashmultiset_iter iter = hms_iter_start(_set_A_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set_B_, value); - size_t max_ = m1 < m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - size_t value = hms_iter_value(&iter1); - size_t m1 = hms_iter_multiplicity(&iter1); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 != m2) - { - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - else - hms_update(_set_r_, value, m2 - m1); - } - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - size_t value = hms_iter_value(&iter2); - size_t m1 = hms_impl_multiplicity_of(_set1_, value); - size_t m2 = hms_iter_multiplicity(&iter2); - if (m1 != m2) - { - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - else - hms_update(_set_r_, value, m2 - m1); - } - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (_set1_->count > _set2_->count) - return 0; - if (hms_empty(_set1_)) - return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 > m2) - return 0; - } - return 1; -} -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - return hms_is_subset(_set2_, _set1_); -} -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (_set1_->count >= _set2_->count) - return 0; - if (hms_empty(_set1_)) - { - if (!hms_empty(_set2_)) - return 1; - else - return 0; - } - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 >= m2) - return 0; - } - return 1; -} -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - return hms_is_proper_subset(_set2_, _set1_); -} -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (hms_empty(_set1_)) - return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - if (hms_impl_get_entry(_set2_, value) != ((void *)0)) - return 0; - } - return 1; -} -_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr) -{ - struct hashmultiset *s_ = _set_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "cardinality:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load, - s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); -} -_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *val_mul_sep) -{ - fprintf(fptr, "%s", start); - size_t last = 0; - for (size_t i = _set_->capacity; i > 0; i--) - { - if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (!_set_->f_val->str(fptr, entry->value)) - return 0; - fprintf(fptr, "%s", val_mul_sep); - if (fprintf(fptr, - "%" - "I64u" - "", - entry->multiplicity) < 0) - return 0; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/hashset.c b/tests/src/cmc/hashset.c deleted file mode 100644 index 0594d98..0000000 --- a/tests/src/cmc/hashset.c +++ /dev/null @@ -1,773 +0,0 @@ - -#include "cmc/hashset.h" - -static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value); -static size_t hs_impl_calculate_size(size_t required); -struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val) -{ - return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); -} -struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_val) - return ((void *)0); - size_t real_capacity = hs_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct hashset *_set_ = alloc->malloc(sizeof(struct hashset)); - if (!_set_) - return ((void *)0); - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry)); - if (!_set_->buffer) - { - alloc->free(_set_); - return ((void *)0); - } - _set_->count = 0; - _set_->capacity = real_capacity; - _set_->load = load; - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - return _set_; -} -void hs_clear(struct hashset *_set_) -{ - if (_set_->f_val->free) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - _set_->f_val->free(entry->value); - } - } - } - memset(_set_->buffer, 0, sizeof(struct hashset_entry) * _set_->capacity); - _set_->count = 0; - _set_->flag = CMC_FLAG_OK; -} -void hs_free(struct hashset *_set_) -{ - if (_set_->f_val->free) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *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 hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _set_->alloc = &cmc_alloc_node_default; - else - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - _set_->flag = CMC_FLAG_OK; -} -_Bool hs_insert(struct hashset *_set_, size_t value) -{ - if (hs_full(_set_)) - { - if (!hs_resize(_set_, _set_->capacity + 1)) - return 0; - } - if (hs_impl_get_entry(_set_, value) != ((void *)0)) - { - _set_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - size_t hash = _set_->f_val->hash(value); - size_t original_pos = hash % _set_->capacity; - size_t pos = original_pos; - struct hashset_entry *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 (1) - { - 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) - { - size_t 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 1; -} -_Bool hs_remove(struct hashset *_set_, size_t value) -{ - if (hs_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashset_entry *result = hs_impl_get_entry(_set_, value); - if (result == ((void *)0)) - { - _set_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - result->value = (size_t){ 0 }; - result->dist = 0; - result->state = CMC_ES_DELETED; - _set_->count--; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->delete) - (_set_)->callbacks->delete (); - ; - return 1; -} -_Bool hs_max(struct hashset *_set_, size_t *value) -{ - if (hs_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t max_val = (size_t){ 0 }; - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - max_val = _set_->buffer[i].value; - first = 0; - } - else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) - { - max_val = _set_->buffer[i].value; - } - } - } - if (value) - *value = max_val; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool hs_min(struct hashset *_set_, size_t *value) -{ - if (hs_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t min_val = (size_t){ 0 }; - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - min_val = _set_->buffer[i].value; - first = 0; - } - else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) - { - min_val = _set_->buffer[i].value; - } - } - } - if (value) - *value = min_val; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool hs_contains(struct hashset *_set_, size_t value) -{ - _set_->flag = CMC_FLAG_OK; - _Bool result = hs_impl_get_entry(_set_, value) != ((void *)0); - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return result; -} -_Bool hs_empty(struct hashset *_set_) -{ - return _set_->count == 0; -} -_Bool hs_full(struct hashset *_set_) -{ - return (double)_set_->capacity * _set_->load <= (double)_set_->count; -} -size_t hs_count(struct hashset *_set_) -{ - return _set_->count; -} -size_t hs_capacity(struct hashset *_set_) -{ - return _set_->capacity; -} -double hs_load(struct hashset *_set_) -{ - return _set_->load; -} -int hs_flag(struct hashset *_set_) -{ - return _set_->flag; -} -_Bool hs_resize(struct hashset *_set_, size_t capacity) -{ - _set_->flag = CMC_FLAG_OK; - if (_set_->capacity == capacity) - goto success; - if (_set_->capacity > capacity / _set_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _set_->load) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t theoretical_size = hs_impl_calculate_size(capacity); - if (theoretical_size < _set_->count / _set_->load) - { - _set_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashset *_new_set_ = hs_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); - if (!_new_set_) - { - _set_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - size_t value = _set_->buffer[i].value; - hs_insert(_new_set_, value); - } - } - if (_set_->count != _new_set_->count) - { - hs_free(_new_set_); - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashset_entry *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; - _new_set_->f_val = &(struct hashset_fval){ ((void *)0) }; - hs_free(_new_set_); -success: - if ((_set_)->callbacks && (_set_)->callbacks->resize) - (_set_)->callbacks->resize(); - ; - return 1; -} -struct hashset *hs_copy_of(struct hashset *_set_) -{ - struct hashset *result = - hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); - if (!result) - { - _set_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _set_->callbacks; - if (_set_->f_val->cpy) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *scan = &(_set_->buffer[i]); - if (scan->state != CMC_ES_EMPTY) - { - struct hashset_entry *target = &(result->buffer[i]); - if (scan->state == CMC_ES_DELETED) - target->state = CMC_ES_DELETED; - else - { - target->state = scan->state; - target->dist = scan->dist; - target->value = _set_->f_val->cpy(scan->value); - } - } - } - } - else - memcpy(result->buffer, _set_->buffer, sizeof(struct hashset_entry) * _set_->capacity); - result->count = _set_->count; - _set_->flag = CMC_FLAG_OK; - return result; -} -_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count != _set2_->count) - return 0; - struct hashset *_set_a_; - struct hashset *_set_b_; - _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; - _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; - for (size_t i = 0; i < _set_a_->capacity; i++) - { - if (_set_a_->buffer[i].state == CMC_ES_FILLED) - { - if (!hs_impl_get_entry(_set_b_, _set_a_->buffer[i].value)) - return 0; - } - } - return 1; -} -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; - struct hashset_entry *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 ((void *)0); -} -static size_t hs_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -struct hashset_iter hs_iter_start(struct hashset *target) -{ - struct hashset_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = 1; - iter.end = hs_empty(target); - if (!hs_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 hashset_iter hs_iter_end(struct hashset *target) -{ - struct hashset_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = hs_empty(target); - iter.end = 1; - if (!hs_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 hs_iter_at_start(struct hashset_iter *iter) -{ - return hs_empty(iter->target) || iter->start; -} -_Bool hs_iter_at_end(struct hashset_iter *iter) -{ - return hs_empty(iter->target) || iter->end; -} -_Bool hs_iter_to_start(struct hashset_iter *iter) -{ - if (!hs_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = hs_empty(iter->target); - return 1; - } - return 0; -} -_Bool hs_iter_to_end(struct hashset_iter *iter) -{ - if (!hs_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = hs_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool hs_iter_next(struct hashset_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = hs_empty(iter->target); - struct hashset_entry *scan = &(iter->target->buffer[iter->cursor]); - iter->index++; - while (1) - { - iter->cursor++; - scan = &(iter->target->buffer[iter->cursor]); - if (scan->state == CMC_ES_FILLED) - break; - } - return 1; -} -_Bool hs_iter_prev(struct hashset_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = hs_empty(iter->target); - struct hashset_entry *scan = &(iter->target->buffer[iter->cursor]); - iter->index--; - while (1) - { - iter->cursor--; - scan = &(iter->target->buffer[iter->cursor]); - if (scan->state == CMC_ES_FILLED) - break; - } - return 1; -} -_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hs_iter_next(iter); - return 1; -} -_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hs_iter_prev(iter); - return 1; -} -_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hs_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hs_iter_advance(iter, index - iter->index); - return 1; -} -size_t hs_iter_value(struct hashset_iter *iter) -{ - if (hs_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor].value; -} -size_t hs_iter_index(struct hashset_iter *iter) -{ - return iter->index; -} -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)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter1 = hs_iter_start(_set1_); - struct hashset_iter iter2 = hs_iter_start(_set2_); - for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) - { - hs_insert(_set_r_, hs_iter_value(&iter1)); - } - for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) - { - hs_insert(_set_r_, hs_iter_value(&iter2)); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -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)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct hashset_iter iter = hs_iter_start(_set_A_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) - hs_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter1 = hs_iter_start(_set1_); - struct hashset_iter iter2 = hs_iter_start(_set2_); - for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) - { - size_t value = hs_iter_value(&iter1); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) - { - size_t value = hs_iter_value(&iter2); - if (hs_impl_get_entry(_set1_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count > _set2_->count) - return 0; - if (hs_empty(_set1_)) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_) -{ - return hs_is_subset(_set2_, _set1_); -} -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count >= _set2_->count) - return 0; - if (hs_empty(_set1_)) - { - if (!hs_empty(_set2_)) - return 1; - else - return 0; - } - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_) -{ - return hs_is_proper_subset(_set2_, _set1_); -} -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (hs_empty(_set1_)) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) != ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_to_string(struct hashset *_set_, FILE *fptr) -{ - struct hashset *s_ = _set_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p }", - "hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, - s_->alloc, (s_)->callbacks); -} -_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - size_t last = 0; - for (size_t i = _set_->capacity; i > 0; i--) - { - if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (!_set_->f_val->str(fptr, entry->value)) - return 0; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/heap.c b/tests/src/cmc/heap.c deleted file mode 100644 index 11cd537..0000000 --- a/tests/src/cmc/heap.c +++ /dev/null @@ -1,424 +0,0 @@ - -#include "cmc/heap.h" - -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) -{ - return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0)); -} -struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct heap *_heap_ = alloc->malloc(sizeof(struct heap)); - if (!_heap_) - return ((void *)0); - _heap_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_heap_->buffer) - { - alloc->free(_heap_); - return ((void *)0); - } - _heap_->capacity = capacity; - _heap_->count = 0; - _heap_->HO = HO; - _heap_->flag = CMC_FLAG_OK; - _heap_->f_val = f_val; - _heap_->alloc = alloc; - (_heap_)->callbacks = callbacks; - return _heap_; -} -void h_clear(struct heap *_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(size_t) * _heap_->capacity); - _heap_->count = 0; - _heap_->flag = CMC_FLAG_OK; -} -void h_free(struct heap *_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 h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _heap_->alloc = &cmc_alloc_node_default; - else - _heap_->alloc = alloc; - (_heap_)->callbacks = callbacks; - _heap_->flag = CMC_FLAG_OK; -} -_Bool h_insert(struct heap *_heap_, size_t value) -{ - if (h_full(_heap_)) - { - if (!h_resize(_heap_, _heap_->count * 2)) - return 0; - } - _heap_->buffer[_heap_->count++] = value; - if (_heap_->count > 1) - { - h_impl_float_up(_heap_, _heap_->count - 1); - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->create) - (_heap_)->callbacks->create(); - ; - return 1; -} -_Bool h_remove(struct heap *_heap_) -{ - if (h_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; - _heap_->buffer[_heap_->count - 1] = (size_t){ 0 }; - _heap_->count--; - h_impl_float_down(_heap_, 0); - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->delete) - (_heap_)->callbacks->delete (); - ; - return 1; -} -size_t h_peek(struct heap *_heap_) -{ - if (h_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - return _heap_->buffer[0]; -} -_Bool h_contains(struct heap *_heap_, size_t value) -{ - _heap_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = 0; i < _heap_->count; i++) - { - if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) - { - result = 1; - break; - } - } - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - return result; -} -_Bool h_empty(struct heap *_heap_) -{ - return _heap_->count == 0; -} -_Bool h_full(struct heap *_heap_) -{ - return _heap_->count >= _heap_->capacity; -} -size_t h_count(struct heap *_heap_) -{ - return _heap_->count; -} -size_t h_capacity(struct heap *_heap_) -{ - return _heap_->capacity; -} -int h_flag(struct heap *_heap_) -{ - return _heap_->flag; -} -_Bool h_resize(struct heap *_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 0; - } - size_t *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity); - if (!new_buffer) - { - _heap_->flag = CMC_FLAG_ALLOC; - return 0; - } - _heap_->buffer = new_buffer; - _heap_->capacity = capacity; -success: - if ((_heap_)->callbacks && (_heap_)->callbacks->resize) - (_heap_)->callbacks->resize(); - ; - return 1; -} -struct heap *h_copy_of(struct heap *_heap_) -{ - struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0)); - if (!result) - { - _heap_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _heap_->callbacks; - if (_heap_->f_val->cpy) - { - for (size_t i = 0; i < _heap_->count; i++) - result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); - } - else - memcpy(result->buffer, _heap_->buffer, sizeof(size_t) * _heap_->count); - result->count = _heap_->count; - _heap_->flag = CMC_FLAG_OK; - return result; -} -_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_) -{ - _heap1_->flag = CMC_FLAG_OK; - _heap2_->flag = CMC_FLAG_OK; - if (_heap1_->count != _heap2_->count) - return 0; - for (size_t i = 0; i < _heap1_->count; i++) - { - if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) - return 0; - } - return 1; -} -static void h_impl_float_up(struct heap *_heap_, size_t index) -{ - size_t C = index; - size_t child = _heap_->buffer[C]; - size_t parent = _heap_->buffer[(index - 1) / 2]; - int mod = _heap_->HO; - while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) - { - size_t tmp = _heap_->buffer[C]; - _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; - _heap_->buffer[(C - 1) / 2] = tmp; - C = (C - 1) / 2; - if (C == 0) - break; - child = _heap_->buffer[C]; - parent = _heap_->buffer[(C - 1) / 2]; - } -} -static void h_impl_float_down(struct heap *_heap_, size_t index) -{ - int mod = _heap_->HO; - while (index < _heap_->count) - { - size_t L = 2 * index + 1; - size_t R = 2 * index + 2; - size_t C = index; - if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) - { - C = L; - } - if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) - { - C = R; - } - if (C != index) - { - size_t tmp = _heap_->buffer[index]; - _heap_->buffer[index] = _heap_->buffer[C]; - _heap_->buffer[C] = tmp; - index = C; - } - else - break; - } -} -struct heap_iter h_iter_start(struct heap *target) -{ - struct heap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = h_empty(target); - return iter; -} -struct heap_iter h_iter_end(struct heap *target) -{ - struct heap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = h_empty(target); - iter.end = 1; - if (!h_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool h_iter_at_start(struct heap_iter *iter) -{ - return h_empty(iter->target) || iter->start; -} -_Bool h_iter_at_end(struct heap_iter *iter) -{ - return h_empty(iter->target) || iter->end; -} -_Bool h_iter_to_start(struct heap_iter *iter) -{ - if (!h_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = h_empty(iter->target); - return 1; - } - return 0; -} -_Bool h_iter_to_end(struct heap_iter *iter) -{ - if (!h_empty(iter->target)) - { - iter->cursor = iter->target->count - 1; - iter->start = h_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool h_iter_next(struct heap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = h_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool h_iter_prev(struct heap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = h_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool h_iter_advance(struct heap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - if (iter->end) - return 0; - iter->start = h_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool h_iter_rewind(struct heap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = h_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool h_iter_go_to(struct heap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return h_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return h_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t h_iter_value(struct heap_iter *iter) -{ - if (h_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t h_iter_index(struct heap_iter *iter) -{ - return iter->cursor; -} -_Bool h_to_string(struct heap *_heap_, FILE *fptr) -{ - struct heap *h_ = _heap_; - const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "type:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p}", - "heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, - (h_)->callbacks); -} -_Bool h_print(struct heap *_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 0; - if (i + 1 < _heap_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/intervalheap.c b/tests/src/cmc/intervalheap.c deleted file mode 100644 index 56ac313..0000000 --- a/tests/src/cmc/intervalheap.c +++ /dev/null @@ -1,686 +0,0 @@ - -#include "cmc/intervalheap.h" - -static void ih_impl_float_up_max(struct intervalheap *_heap_); -static void ih_impl_float_up_min(struct intervalheap *_heap_); -static void ih_impl_float_down_max(struct intervalheap *_heap_); -static void ih_impl_float_down_min(struct intervalheap *_heap_); -struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) -{ - return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || capacity == 0xffffffffffffffffULL) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap)); - if (!_heap_) - return ((void *)0); - capacity = (capacity + capacity % 2) / 2; - _heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2])); - if (!_heap_->buffer) - { - alloc->free(_heap_); - return ((void *)0); - } - _heap_->capacity = capacity; - _heap_->size = 0; - _heap_->count = 0; - _heap_->flag = CMC_FLAG_OK; - _heap_->f_val = f_val; - _heap_->alloc = alloc; - (_heap_)->callbacks = callbacks; - return _heap_; -} -void ih_clear(struct intervalheap *_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(size_t[2]) * _heap_->capacity); - _heap_->size = 0; - _heap_->count = 0; - _heap_->flag = CMC_FLAG_OK; -} -void ih_free(struct intervalheap *_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 ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _heap_->alloc = &cmc_alloc_node_default; - else - _heap_->alloc = alloc; - (_heap_)->callbacks = callbacks; - _heap_->flag = CMC_FLAG_OK; -} -_Bool ih_insert(struct intervalheap *_heap_, size_t value) -{ - if (ih_full(_heap_)) - { - if (!ih_resize(_heap_, _heap_->capacity * 4)) - return 0; - } - if (_heap_->count % 2 == 0) - { - _heap_->buffer[_heap_->size][0] = value; - _heap_->buffer[_heap_->size][1] = (size_t){ 0 }; - _heap_->size++; - } - else - { - size_t(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); - if (_heap_->f_val->cmp((*node)[0], value) > 0) - { - (*node)[1] = (*node)[0]; - (*node)[0] = value; - } - else - { - (*node)[1] = value; - } - } - _heap_->count++; - _heap_->flag = CMC_FLAG_OK; - if (_heap_->count > 2) - { - size_t(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); - if (_heap_->f_val->cmp((*parent)[0], value) > 0) - ih_impl_float_up_min(_heap_); - else if (_heap_->f_val->cmp((*parent)[1], value) < 0) - ih_impl_float_up_max(_heap_); - } - if ((_heap_)->callbacks && (_heap_)->callbacks->create) - (_heap_)->callbacks->create(); - ; - return 1; -} -_Bool ih_remove_max(struct intervalheap *_heap_) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (_heap_->count == 1) - { - _heap_->buffer[0][0] = (size_t){ 0 }; - _heap_->count--; - _heap_->size--; - goto success; - } - size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); - if (_heap_->count % 2 == 1) - { - _heap_->buffer[0][1] = (*last_node)[0]; - (*last_node)[0] = (size_t){ 0 }; - _heap_->size--; - } - else - { - _heap_->buffer[0][1] = (*last_node)[1]; - (*last_node)[1] = (size_t){ 0 }; - } - _heap_->count--; - ih_impl_float_down_max(_heap_); -success: - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->delete) - (_heap_)->callbacks->delete (); - ; - return 1; -} -_Bool ih_remove_min(struct intervalheap *_heap_) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (_heap_->count == 1) - { - _heap_->buffer[0][0] = (size_t){ 0 }; - _heap_->count--; - _heap_->size--; - goto success; - } - size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); - _heap_->buffer[0][0] = (*last_node)[0]; - if (_heap_->count % 2 == 1) - { - (*last_node)[0] = (size_t){ 0 }; - _heap_->size--; - } - else - { - (*last_node)[0] = (*last_node)[1]; - (*last_node)[1] = (size_t){ 0 }; - } - _heap_->count--; - ih_impl_float_down_min(_heap_); -success: - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->delete) - (_heap_)->callbacks->delete (); - ; - return 1; -} -_Bool ih_update_max(struct intervalheap *_heap_, size_t value) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (_heap_->count == 1) - { - _heap_->buffer[0][0] = value; - } - else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0) - { - _heap_->buffer[0][1] = _heap_->buffer[0][0]; - _heap_->buffer[0][0] = value; - ih_impl_float_down_max(_heap_); - } - else - { - _heap_->buffer[0][1] = value; - ih_impl_float_down_max(_heap_); - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->update) - (_heap_)->callbacks->update(); - ; - return 1; -} -_Bool ih_update_min(struct intervalheap *_heap_, size_t value) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (_heap_->count == 1) - { - _heap_->buffer[0][0] = value; - } - else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) - { - _heap_->buffer[0][0] = _heap_->buffer[0][1]; - _heap_->buffer[0][1] = value; - ih_impl_float_down_min(_heap_); - } - else - { - _heap_->buffer[0][0] = value; - ih_impl_float_down_min(_heap_); - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->update) - (_heap_)->callbacks->update(); - ; - return 1; -} -size_t ih_max(struct intervalheap *_heap_) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - if (_heap_->count == 1) - return _heap_->buffer[0][0]; - return _heap_->buffer[0][1]; -} -size_t ih_min(struct intervalheap *_heap_) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - return _heap_->buffer[0][0]; -} -_Bool ih_contains(struct intervalheap *_heap_, size_t value) -{ - _heap_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = 0; i < _heap_->count; i++) - { - if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0) - { - result = 1; - break; - } - } - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - return result; -} -_Bool ih_empty(struct intervalheap *_heap_) -{ - return _heap_->count == 0; -} -_Bool ih_full(struct intervalheap *_heap_) -{ - return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; -} -size_t ih_count(struct intervalheap *_heap_) -{ - return _heap_->count; -} -size_t ih_capacity(struct intervalheap *_heap_) -{ - return _heap_->capacity; -} -int ih_flag(struct intervalheap *_heap_) -{ - return _heap_->flag; -} -_Bool ih_resize(struct intervalheap *_heap_, size_t capacity) -{ - if (_heap_->capacity == capacity) - goto success; - if (capacity < _heap_->count) - { - _heap_->flag = CMC_FLAG_INVALID; - return 0; - } - if (capacity == 0xffffffffffffffffULL) - { - _heap_->flag = CMC_FLAG_ERROR; - return 0; - } - capacity += capacity % 2; - size_t(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity); - if (!new_buffer) - { - _heap_->flag = CMC_FLAG_ALLOC; - return 0; - } - if (capacity > _heap_->capacity) - { - memset(new_buffer + _heap_->capacity, 0, sizeof(size_t[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 1; -} -struct intervalheap *ih_copy_of(struct intervalheap *_heap_) -{ - 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); - if (!result->buffer) - { - _heap_->alloc->free(result); - _heap_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - 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(size_t[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 ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_) -{ - _heap1_->flag = CMC_FLAG_OK; - _heap2_->flag = CMC_FLAG_OK; - if (_heap1_->count != _heap2_->count) - return 0; - for (size_t i = 0; i < _heap1_->count; i++) - { - size_t value1 = _heap1_->buffer[i / 2][i % 2]; - size_t value2 = _heap2_->buffer[i / 2][i % 2]; - if (_heap1_->f_val->cmp(value1, value2) != 0) - return 0; - } - return 1; -} -static void ih_impl_float_up_max(struct intervalheap *_heap_) -{ - size_t index = _heap_->size - 1; - size_t(*curr_node)[2] = &(_heap_->buffer[index]); - while (index > 0) - { - size_t P_index = (index - 1) / 2; - size_t(*parent)[2] = &(_heap_->buffer[P_index]); - if (index == _heap_->size - 1 && _heap_->count % 2 != 0) - { - if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0) - break; - size_t tmp = (*curr_node)[0]; - (*curr_node)[0] = (*parent)[1]; - (*parent)[1] = tmp; - } - else - { - if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0) - break; - size_t tmp = (*curr_node)[1]; - (*curr_node)[1] = (*parent)[1]; - (*parent)[1] = tmp; - } - index = P_index; - curr_node = parent; - } -} -static void ih_impl_float_up_min(struct intervalheap *_heap_) -{ - size_t index = _heap_->size - 1; - size_t(*curr_node)[2] = &(_heap_->buffer[index]); - while (index > 0) - { - size_t P_index = (index - 1) / 2; - size_t(*parent)[2] = &(_heap_->buffer[P_index]); - if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) - break; - size_t tmp = (*curr_node)[0]; - (*curr_node)[0] = (*parent)[0]; - (*parent)[0] = tmp; - index = P_index; - curr_node = parent; - } -} -static void ih_impl_float_down_max(struct intervalheap *_heap_) -{ - size_t index = 0; - size_t(*curr_node)[2] = &(_heap_->buffer[index]); - while (1) - { - if (2 * index + 1 >= _heap_->size) - break; - size_t child; - size_t L_index = index * 2 + 1; - size_t R_index = index * 2 + 2; - if (R_index < _heap_->size) - { - 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; - else - child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index; - } - else - child = L_index; - size_t(*child_node)[2] = &(_heap_->buffer[child]); - if (child == _heap_->size - 1 && _heap_->count % 2 != 0) - { - if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0) - break; - size_t tmp = (*child_node)[0]; - (*child_node)[0] = (*curr_node)[1]; - (*curr_node)[1] = tmp; - } - else - { - if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0) - break; - size_t tmp = (*child_node)[1]; - (*child_node)[1] = (*curr_node)[1]; - (*curr_node)[1] = tmp; - if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) - { - tmp = (*child_node)[0]; - (*child_node)[0] = (*child_node)[1]; - (*child_node)[1] = tmp; - } - } - index = child; - curr_node = child_node; - } -} -static void ih_impl_float_down_min(struct intervalheap *_heap_) -{ - size_t index = 0; - size_t(*curr_node)[2] = &(_heap_->buffer[index]); - while (1) - { - if (2 * index + 1 >= _heap_->size) - break; - size_t child; - size_t L_index = index * 2 + 1; - size_t R_index = index * 2 + 2; - if (R_index < _heap_->size) - { - 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; - } - else - child = L_index; - size_t(*child_node)[2] = &(_heap_->buffer[child]); - if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) - break; - size_t tmp = (*child_node)[0]; - (*child_node)[0] = (*curr_node)[0]; - (*curr_node)[0] = tmp; - if (child != _heap_->size - 1 || _heap_->count % 2 == 0) - { - if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) - { - tmp = (*child_node)[0]; - (*child_node)[0] = (*child_node)[1]; - (*child_node)[1] = tmp; - } - } - index = child; - curr_node = child_node; - } -} -struct intervalheap_iter ih_iter_start(struct intervalheap *target) -{ - struct intervalheap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = ih_empty(target); - return iter; -} -struct intervalheap_iter ih_iter_end(struct intervalheap *target) -{ - struct intervalheap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = ih_empty(target); - iter.end = 1; - if (!ih_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool ih_iter_at_start(struct intervalheap_iter *iter) -{ - return ih_empty(iter->target) || iter->start; -} -_Bool ih_iter_at_end(struct intervalheap_iter *iter) -{ - return ih_empty(iter->target) || iter->end; -} -_Bool ih_iter_to_start(struct intervalheap_iter *iter) -{ - if (!ih_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = ih_empty(iter->target); - return 1; - } - return 0; -} -_Bool ih_iter_to_end(struct intervalheap_iter *iter) -{ - if (!ih_empty(iter->target)) - { - iter->cursor = iter->target->count - 1; - iter->start = ih_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool ih_iter_next(struct intervalheap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = ih_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool ih_iter_prev(struct intervalheap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = ih_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - if (iter->end) - return 0; - iter->start = ih_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = ih_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return ih_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return ih_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t ih_iter_value(struct intervalheap_iter *iter) -{ - if (ih_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; -} -size_t ih_iter_index(struct intervalheap_iter *iter) -{ - return iter->cursor; -} -_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr) -{ - struct intervalheap *h_ = _heap_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "size:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, - h_->f_val, h_->alloc, (h_)->callbacks); -} -_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = 0; i < _heap_->count; i++) - { - if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) - return 0; - if (i + 1 < _heap_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/linkedlist.c b/tests/src/cmc/linkedlist.c deleted file mode 100644 index 32dbae8..0000000 --- a/tests/src/cmc/linkedlist.c +++ /dev/null @@ -1,683 +0,0 @@ - -#include "cmc/linkedlist.h" - -struct linkedlist *ll_new(struct linkedlist_fval *f_val) -{ - return ll_new_custom(f_val, ((void *)0), ((void *)0)); -} -struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist)); - if (!_list_) - return ((void *)0); - _list_->count = 0; - _list_->head = ((void *)0); - _list_->tail = ((void *)0); - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - return _list_; -} -void ll_clear(struct linkedlist *_list_) -{ - struct linkedlist_node *scan = _list_->head; - while (_list_->head != ((void *)0)) - { - _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 = ((void *)0); - _list_->tail = ((void *)0); - _list_->flag = CMC_FLAG_OK; -} -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) -{ - ; - if (!alloc) - _list_->alloc = &cmc_alloc_node_default; - else - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - _list_->flag = CMC_FLAG_OK; -} -_Bool ll_push_front(struct linkedlist *_list_, size_t value) -{ - struct linkedlist_node *_node_ = ll_new_node(_list_, value); - if (!_node_) - return 0; - if (ll_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 1; -} -_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) -{ - if (index > _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (index == 0) - { - return ll_push_front(_list_, value); - } - else if (index == _list_->count) - { - return ll_push_back(_list_, value); - } - struct linkedlist_node *_node_ = ll_new_node(_list_, value); - if (!_node_) - return 0; - struct linkedlist_node *scan = ll_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 1; -} -_Bool ll_push_back(struct linkedlist *_list_, size_t value) -{ - struct linkedlist_node *_node_ = ll_new_node(_list_, value); - if (!_node_) - return 0; - if (ll_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 1; -} -_Bool ll_pop_front(struct linkedlist *_list_) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct linkedlist_node *_node_ = _list_->head; - _list_->head = _list_->head->next; - _list_->alloc->free(_node_); - if (_list_->head == ((void *)0)) - _list_->tail = ((void *)0); - else - _list_->head->prev = ((void *)0); - _list_->count--; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -_Bool ll_pop_at(struct linkedlist *_list_, size_t index) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (index == 0) - { - return ll_pop_front(_list_); - } - else if (index == _list_->count - 1) - { - return ll_pop_back(_list_); - } - struct linkedlist_node *_node_ = ll_get_node(_list_, index); - if (!_node_) - return 0; - _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 1; -} -_Bool ll_pop_back(struct linkedlist *_list_) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct linkedlist_node *_node_ = _list_->tail; - _list_->tail = _list_->tail->prev; - _list_->alloc->free(_node_); - if (_list_->tail == ((void *)0)) - _list_->head = ((void *)0); - else - _list_->tail->next = ((void *)0); - _list_->count--; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -size_t ll_front(struct linkedlist *_list_) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->head->value; -} -size_t ll_get(struct linkedlist *_list_, size_t index) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return (size_t){ 0 }; - } - struct linkedlist_node *scan = ll_get_node(_list_, index); - if (scan == ((void *)0)) - return (size_t){ 0 }; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return scan->value; -} -size_t *ll_get_ref(struct linkedlist *_list_, size_t index) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - struct linkedlist_node *scan = ll_get_node(_list_, index); - if (scan == ((void *)0)) - return ((void *)0); - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return &(scan->value); -} -size_t ll_back(struct linkedlist *_list_) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->tail->value; -} -_Bool ll_contains(struct linkedlist *_list_, size_t value) -{ - _list_->flag = CMC_FLAG_OK; - _Bool result = 0; - struct linkedlist_node *scan = _list_->head; - while (scan != ((void *)0)) - { - if (_list_->f_val->cmp(scan->value, value) == 0) - { - result = 1; - break; - } - scan = scan->next; - } - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return result; -} -_Bool ll_empty(struct linkedlist *_list_) -{ - return _list_->count == 0; -} -size_t ll_count(struct linkedlist *_list_) -{ - return _list_->count; -} -int ll_flag(struct linkedlist *_list_) -{ - return _list_->flag; -} -struct linkedlist *ll_copy_of(struct linkedlist *_list_) -{ - struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0)); - if (!result) - return ((void *)0); - (result)->callbacks = _list_->callbacks; - struct linkedlist_node *scan = _list_->head; - while (scan != ((void *)0)) - { - struct linkedlist_node *new_node; - if (_list_->f_val->cpy) - new_node = ll_new_node(_list_, _list_->f_val->cpy(scan->value)); - else - new_node = ll_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 ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) -{ - _list1_->flag = CMC_FLAG_OK; - _list2_->flag = CMC_FLAG_OK; - if (_list1_->count != _list2_->count) - return 0; - struct linkedlist_node *scan1 = _list1_->head; - struct linkedlist_node *scan2 = _list2_->head; - while (scan1 != ((void *)0) && scan2 != ((void *)0)) - { - if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) - return 0; - scan1 = scan1->next; - scan2 = scan2->next; - } - return 1; -} -struct linkedlist_iter ll_iter_start(struct linkedlist *target) -{ - struct linkedlist_iter iter; - iter.target = target; - iter.cursor = target->head; - iter.index = 0; - iter.start = 1; - iter.end = ll_empty(target); - return iter; -} -struct linkedlist_iter ll_iter_end(struct linkedlist *target) -{ - struct linkedlist_iter iter; - iter.target = target; - iter.cursor = target->tail; - iter.index = 0; - iter.start = ll_empty(target); - iter.end = 1; - if (!ll_empty(target)) - iter.index = target->count - 1; - return iter; -} -_Bool ll_iter_at_start(struct linkedlist_iter *iter) -{ - return ll_empty(iter->target) || iter->start; -} -_Bool ll_iter_at_end(struct linkedlist_iter *iter) -{ - return ll_empty(iter->target) || iter->end; -} -_Bool ll_iter_to_start(struct linkedlist_iter *iter) -{ - if (!ll_empty(iter->target)) - { - iter->cursor = iter->target->head; - iter->index = 0; - iter->start = 1; - iter->end = ll_empty(iter->target); - return 1; - } - return 0; -} -_Bool ll_iter_to_end(struct linkedlist_iter *iter) -{ - if (!ll_empty(iter->target)) - { - iter->cursor = iter->target->tail; - iter->index = iter->target->count - 1; - iter->start = ll_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool ll_iter_next(struct linkedlist_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor->next == ((void *)0)) - { - iter->end = 1; - return 0; - } - iter->start = ll_empty(iter->target); - iter->cursor = iter->cursor->next; - iter->index++; - return 1; -} -_Bool ll_iter_prev(struct linkedlist_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor->prev == ((void *)0)) - { - iter->start = 1; - return 0; - } - iter->end = ll_empty(iter->target); - iter->cursor = iter->cursor->prev; - iter->index--; - return 1; -} -_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor->next == ((void *)0)) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - iter->start = ll_empty(iter->target); - iter->index += steps; - for (size_t i = 0; i < steps; i++) - iter->cursor = iter->cursor->next; - return 1; -} -_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor->prev == ((void *)0)) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - iter->end = ll_empty(iter->target); - iter->index -= steps; - for (size_t i = 0; i < steps; i++) - iter->cursor = iter->cursor->prev; - return 1; -} -_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return ll_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return ll_iter_advance(iter, index - iter->index); - return 1; -} -size_t ll_iter_value(struct linkedlist_iter *iter) -{ - if (ll_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->value; -} -size_t *ll_iter_rvalue(struct linkedlist_iter *iter) -{ - if (ll_empty(iter->target)) - return ((void *)0); - return &(iter->cursor->value); -} -size_t ll_iter_index(struct linkedlist_iter *iter) -{ - return iter->index; -} -struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter) -{ - return iter->cursor; -} -struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) -{ - struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node)); - if (!_node_) - { - _list_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - _node_->value = value; - _node_->next = ((void *)0); - _node_->prev = ((void *)0); - return _node_; -} -void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_) -{ - _list_->alloc->free(_node_); -} -struct linkedlist_node *ll_head(struct linkedlist *_list_) -{ - return _list_->head; -} -struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - struct linkedlist_node *_node_ = ((void *)0); - 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 linkedlist_node *ll_tail(struct linkedlist *_list_) -{ - return _list_->tail; -} -_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) - return 0; - new_node->next = _node_->next; - if (_node_->next != ((void *)0)) - _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 1; -} -_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) - return 0; - new_node->prev = _node_->prev; - if (_node_->prev != ((void *)0)) - _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 1; -} -_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_) -{ - if (_node_->next == ((void *)0)) - { - _owner_->flag = CMC_FLAG_INVALID; - return 0; - } - struct linkedlist_node *tmp = _node_->next; - _node_->next = _node_->next->next; - if (tmp->next != ((void *)0)) - tmp->next->prev = _node_; - else - _owner_->tail = _node_; - _owner_->alloc->free(tmp); - _owner_->count--; - _owner_->flag = CMC_FLAG_OK; - return 1; -} -_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_) -{ - if (_node_->prev != ((void *)0)) - _node_->prev->next = _node_->next; - else - _owner_->head = _node_->next; - if (_node_->next != ((void *)0)) - _node_->next->prev = _node_->prev; - else - _owner_->tail = _node_->prev; - _owner_->alloc->free(_node_); - _owner_->count--; - _owner_->flag = CMC_FLAG_OK; - return 1; -} -_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_) -{ - if (_node_->prev == ((void *)0)) - { - _owner_->flag = CMC_FLAG_INVALID; - return 0; - } - struct linkedlist_node *tmp = _node_->prev; - _node_->prev = _node_->prev->prev; - if (tmp->prev != ((void *)0)) - tmp->prev->next = _node_; - else - _owner_->head = _node_; - _owner_->alloc->free(tmp); - _owner_->count--; - _owner_->flag = CMC_FLAG_OK; - return 1; -} -struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_) -{ - return _node_->next; -} -struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_) -{ - return _node_->prev; -} -_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr) -{ - struct linkedlist *l_ = _list_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "count:%" - "I64u" - ", " - "head:%p, " - "tail:%p, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, - (l_)->callbacks); -} -_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - struct linkedlist_node *scan = _list_->head; - while (scan != ((void *)0)) - { - if (!_list_->f_val->str(fptr, scan->value)) - return 0; - scan = scan->next; - if (scan) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/list.c b/tests/src/cmc/list.c deleted file mode 100644 index 6d65763..0000000 --- a/tests/src/cmc/list.c +++ /dev/null @@ -1,643 +0,0 @@ - -#include "cmc/list.h" - -struct list *l_new(size_t capacity, struct list_fval *f_val) -{ - return l_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct list *_list_ = alloc->malloc(sizeof(struct list)); - if (!_list_) - return ((void *)0); - _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_list_->buffer) - { - alloc->free(_list_); - return ((void *)0); - } - _list_->capacity = capacity; - _list_->count = 0; - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - return _list_; -} -void l_clear(struct list *_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(size_t) * _list_->capacity); - _list_->count = 0; - _list_->flag = CMC_FLAG_OK; -} -void l_free(struct list *_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 l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _list_->alloc = &cmc_alloc_node_default; - else - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - _list_->flag = CMC_FLAG_OK; -} -_Bool l_push_front(struct list *_list_, size_t value) -{ - if (l_full(_list_)) - { - if (!l_resize(_list_, _list_->count * 2)) - return 0; - } - if (!l_empty(_list_)) - { - memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(size_t)); - } - _list_->buffer[0] = value; - _list_->count++; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_push_at(struct list *_list_, size_t value, size_t index) -{ - if (index > _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (l_full(_list_)) - { - if (!l_resize(_list_, _list_->count * 2)) - return 0; - } - 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; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_push_back(struct list *_list_, size_t value) -{ - if (l_full(_list_)) - { - if (!l_resize(_list_, _list_->count * 2)) - return 0; - } - _list_->buffer[_list_->count++] = value; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_pop_front(struct list *_list_) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); - _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -_Bool l_pop_at(struct list *_list_, size_t index) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); - _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -_Bool l_pop_back(struct list *_list_) -{ - if (l_empty(_list_)) - return 0; - _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -size_t l_front(struct list *_list_) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[0]; -} -size_t l_get(struct list *_list_, size_t index) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[index]; -} -size_t *l_get_ref(struct list *_list_, size_t index) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return &(_list_->buffer[index]); -} -size_t l_back(struct list *_list_) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[_list_->count - 1]; -} -size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) -{ - _list_->flag = CMC_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 l_contains(struct list *_list_, size_t value) -{ - _list_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = 0; i < _list_->count; i++) - { - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) - { - result = 1; - break; - } - } - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return result; -} -_Bool l_empty(struct list *_list_) -{ - return _list_->count == 0; -} -_Bool l_full(struct list *_list_) -{ - return _list_->count >= _list_->capacity; -} -size_t l_count(struct list *_list_) -{ - return _list_->count; -} -_Bool l_fits(struct list *_list_, size_t size) -{ - return _list_->count + size <= _list_->capacity; -} -size_t l_capacity(struct list *_list_) -{ - return _list_->capacity; -} -int l_flag(struct list *_list_) -{ - return _list_->flag; -} -_Bool l_resize(struct list *_list_, size_t capacity) -{ - _list_->flag = CMC_FLAG_OK; - if (_list_->capacity == capacity) - return 1; - if (capacity < _list_->count) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); - if (!new_buffer) - { - _list_->flag = CMC_FLAG_ALLOC; - return 0; - } - _list_->buffer = new_buffer; - _list_->capacity = capacity; - if ((_list_)->callbacks && (_list_)->callbacks->resize) - (_list_)->callbacks->resize(); - ; - return 1; -} -struct list *l_copy_of(struct list *_list_) -{ - struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); - if (!result) - { - _list_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - (result)->callbacks = _list_->callbacks; - if (_list_->f_val->cpy) - { - for (size_t i = 0; i < _list_->count; i++) - result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); - } - else - memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); - result->count = _list_->count; - _list_->flag = CMC_FLAG_OK; - return result; -} -_Bool l_equals(struct list *_list1_, struct list *_list2_) -{ - _list1_->flag = CMC_FLAG_OK; - _list2_->flag = CMC_FLAG_OK; - if (_list1_->count != _list2_->count) - return 0; - for (size_t i = 0; i < _list1_->count; i++) - { - if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) - return 0; - } - return 1; -} -struct list_iter l_iter_start(struct list *target) -{ - struct list_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = l_empty(target); - return iter; -} -struct list_iter l_iter_end(struct list *target) -{ - struct list_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = l_empty(target); - iter.end = 1; - if (!l_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool l_iter_at_start(struct list_iter *iter) -{ - return l_empty(iter->target) || iter->start; -} -_Bool l_iter_at_end(struct list_iter *iter) -{ - return l_empty(iter->target) || iter->end; -} -_Bool l_iter_to_start(struct list_iter *iter) -{ - if (!l_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = l_empty(iter->target); - return 1; - } - return 0; -} -_Bool l_iter_to_end(struct list_iter *iter) -{ - if (!l_empty(iter->target)) - { - iter->start = l_empty(iter->target); - iter->cursor = iter->target->count - 1; - iter->end = 1; - return 1; - } - return 0; -} -_Bool l_iter_next(struct list_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = l_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool l_iter_prev(struct list_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = l_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool l_iter_advance(struct list_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - iter->start = l_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool l_iter_rewind(struct list_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = l_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool l_iter_go_to(struct list_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return l_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return l_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t l_iter_value(struct list_iter *iter) -{ - if (l_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t *l_iter_rvalue(struct list_iter *iter) -{ - if (l_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor]); -} -size_t l_iter_index(struct list_iter *iter) -{ - return iter->cursor; -} -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); - memcpy(_list_->buffer, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (index > _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (index == 0) - return l_seq_push_front(_list_, values, size); - else if (index == _list_->count) - return l_seq_push_back(_list_, values, size); - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); - memcpy(_list_->buffer + index, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) -{ - if (from > to) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (to >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - size_t length = (to - from + 1); - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); - _list_->count -= to - from + 1; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) -{ - if (from > to) - { - _list_->flag = CMC_FLAG_INVALID; - return ((void *)0); - } - if (to >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - size_t length = to - from + 1; - struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks); - if (!result) - { - _list_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); - _list_->count -= length; - result->count = length; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return result; -} -_Bool l_to_string(struct list *_list_, FILE *fptr) -{ - struct list *l_ = _list_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, - (l_)->callbacks); -} -_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = 0; i < _list_->count; i++) - { - if (!_list_->f_val->str(fptr, _list_->buffer[i])) - return 0; - if (i + 1 < _list_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/queue.c b/tests/src/cmc/queue.c deleted file mode 100644 index de55581..0000000 --- a/tests/src/cmc/queue.c +++ /dev/null @@ -1,431 +0,0 @@ - -#include "cmc/queue.h" - -struct queue *q_new(size_t capacity, struct queue_fval *f_val) -{ - return q_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct queue *_queue_ = alloc->malloc(sizeof(struct queue)); - if (!_queue_) - return ((void *)0); - _queue_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_queue_->buffer) - { - alloc->free(_queue_); - return ((void *)0); - } - _queue_->capacity = capacity; - _queue_->count = 0; - _queue_->front = 0; - _queue_->back = 0; - _queue_->flag = CMC_FLAG_OK; - _queue_->f_val = f_val; - _queue_->alloc = alloc; - (_queue_)->callbacks = callbacks; - return _queue_; -} -void q_clear(struct queue *_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(size_t) * _queue_->capacity); - _queue_->count = 0; - _queue_->front = 0; - _queue_->back = 0; - _queue_->flag = CMC_FLAG_OK; -} -void q_free(struct queue *_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 q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _queue_->alloc = &cmc_alloc_node_default; - else - _queue_->alloc = alloc; - (_queue_)->callbacks = callbacks; - _queue_->flag = CMC_FLAG_OK; -} -_Bool q_enqueue(struct queue *_queue_, size_t value) -{ - if (q_full(_queue_)) - { - if (!q_resize(_queue_, _queue_->capacity * 2)) - return 0; - } - _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 1; -} -_Bool q_dequeue(struct queue *_queue_) -{ - if (q_empty(_queue_)) - { - _queue_->flag = CMC_FLAG_EMPTY; - return 0; - } - _queue_->buffer[_queue_->front] = (size_t){ 0 }; - _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; - _queue_->count--; - _queue_->flag = CMC_FLAG_OK; - if ((_queue_)->callbacks && (_queue_)->callbacks->delete) - (_queue_)->callbacks->delete (); - ; - return 1; -} -size_t q_peek(struct queue *_queue_) -{ - if (q_empty(_queue_)) - { - _queue_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _queue_->flag = CMC_FLAG_OK; - if ((_queue_)->callbacks && (_queue_)->callbacks->read) - (_queue_)->callbacks->read(); - ; - return _queue_->buffer[_queue_->front]; -} -_Bool q_contains(struct queue *_queue_, size_t value) -{ - _queue_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) - { - result = 1; - break; - } - i = (i + 1) % _queue_->capacity; - } - if ((_queue_)->callbacks && (_queue_)->callbacks->read) - (_queue_)->callbacks->read(); - ; - return result; -} -_Bool q_empty(struct queue *_queue_) -{ - return _queue_->count == 0; -} -_Bool q_full(struct queue *_queue_) -{ - return _queue_->count >= _queue_->capacity; -} -size_t q_count(struct queue *_queue_) -{ - return _queue_->count; -} -size_t q_capacity(struct queue *_queue_) -{ - return _queue_->capacity; -} -int q_flag(struct queue *_queue_) -{ - return _queue_->flag; -} -_Bool q_resize(struct queue *_queue_, size_t capacity) -{ - if (_queue_->capacity == capacity) - goto success; - if (capacity < _queue_->count) - { - _queue_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _queue_->alloc->malloc(sizeof(size_t) * capacity); - if (!new_buffer) - { - _queue_->flag = CMC_FLAG_ALLOC; - return 0; - } - 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 1; -} -struct queue *q_copy_of(struct queue *_queue_) -{ - struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0)); - if (!result) - { - _queue_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _queue_->callbacks; - if (_queue_->f_val->cpy) - { - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - 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 q_equals(struct queue *_queue1_, struct queue *_queue2_) -{ - _queue1_->flag = CMC_FLAG_OK; - _queue2_->flag = CMC_FLAG_OK; - 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++) - { - if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) - return 0; - i = (i + 1) % _queue1_->capacity; - j = (j + 1) % _queue2_->capacity; - } - return 1; -} -struct queue_iter q_iter_start(struct queue *target) -{ - struct queue_iter iter; - iter.target = target; - iter.cursor = target->front; - iter.index = 0; - iter.start = 1; - iter.end = q_empty(target); - return iter; -} -struct queue_iter q_iter_end(struct queue *target) -{ - struct queue_iter iter; - iter.target = target; - if (!q_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 = q_empty(target); - iter.end = 1; - return iter; -} -_Bool q_iter_at_start(struct queue_iter *iter) -{ - return q_empty(iter->target) || iter->start; -} -_Bool q_iter_at_end(struct queue_iter *iter) -{ - return q_empty(iter->target) || iter->end; -} -_Bool q_iter_to_start(struct queue_iter *iter) -{ - if (!q_empty(iter->target)) - { - iter->cursor = iter->target->front; - iter->index = 0; - iter->start = 1; - iter->end = 0; - return 1; - } - return 0; -} -_Bool q_iter_to_end(struct queue_iter *iter) -{ - if (!q_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 = 0; - iter->end = 1; - return 1; - } - return 0; -} -_Bool q_iter_next(struct queue_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = q_empty(iter->target); - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); - iter->index++; - return 1; -} -_Bool q_iter_prev(struct queue_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = q_empty(iter->target); - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; - iter->index--; - return 1; -} -_Bool q_iter_advance(struct queue_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - iter->start = q_empty(iter->target); - iter->index += steps; - iter->cursor = (iter->cursor + steps) % iter->target->capacity; - return 1; -} -_Bool q_iter_rewind(struct queue_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - iter->end = q_empty(iter->target); - iter->index -= steps; - if (iter->cursor < steps) - iter->cursor += iter->target->capacity; - iter->cursor -= steps; - return 1; -} -_Bool q_iter_go_to(struct queue_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return q_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return q_iter_advance(iter, index - iter->index); - return 1; -} -size_t q_iter_value(struct queue_iter *iter) -{ - if (q_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t *q_iter_rvalue(struct queue_iter *iter) -{ - if (q_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor]); -} -size_t q_iter_index(struct queue_iter *iter) -{ - return iter->index; -} -_Bool q_to_string(struct queue *_queue_, FILE *fptr) -{ - struct queue *q_ = _queue_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "front:%" - "I64u" - ", " - "back:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag, - q_->f_val, q_->alloc, (q_)->callbacks); -} -_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) - return 0; - i = (i + 1) % _queue_->capacity; - if (j + 1 < _queue_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/sortedlist.c b/tests/src/cmc/sortedlist.c deleted file mode 100644 index d130322..0000000 --- a/tests/src/cmc/sortedlist.c +++ /dev/null @@ -1,512 +0,0 @@ - -#include "cmc/sortedlist.h" - -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) -{ - return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist)); - if (!_list_) - return ((void *)0); - _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_list_->buffer) - { - alloc->free(_list_); - return ((void *)0); - } - _list_->capacity = capacity; - _list_->count = 0; - _list_->is_sorted = 0; - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - return _list_; -} -void sl_clear(struct sortedlist *_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(size_t) * _list_->capacity); - _list_->count = 0; - _list_->flag = CMC_FLAG_OK; -} -void sl_free(struct sortedlist *_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 sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _list_->alloc = &cmc_alloc_node_default; - else - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - _list_->flag = CMC_FLAG_OK; -} -_Bool sl_insert(struct sortedlist *_list_, size_t value) -{ - if (sl_full(_list_)) - { - if (!sl_resize(_list_, _list_->capacity * 2)) - return 0; - } - _list_->buffer[_list_->count++] = value; - _list_->is_sorted = 0; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool sl_remove(struct sortedlist *_list_, size_t index) -{ - if (sl_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); - _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -size_t sl_max(struct sortedlist *_list_) -{ - if (sl_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - sl_sort(_list_); - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[_list_->count - 1]; -} -size_t sl_min(struct sortedlist *_list_) -{ - if (sl_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - sl_sort(_list_); - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[0]; -} -size_t sl_get(struct sortedlist *_list_, size_t index) -{ - if (sl_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return (size_t){ 0 }; - } - sl_sort(_list_); - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[index]; -} -size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start) -{ - _list_->flag = CMC_FLAG_OK; - sl_sort(_list_); - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - if (from_start) - { - return sl_impl_binary_search_first(_list_, value); - } - return sl_impl_binary_search_last(_list_, value); -} -_Bool sl_contains(struct sortedlist *_list_, size_t value) -{ - _list_->flag = CMC_FLAG_OK; - if (sl_empty(_list_)) - return 0; - sl_sort(_list_); - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return sl_impl_binary_search_first(_list_, value) < _list_->count; -} -_Bool sl_empty(struct sortedlist *_list_) -{ - return _list_->count == 0; -} -_Bool sl_full(struct sortedlist *_list_) -{ - return _list_->count >= _list_->capacity; -} -size_t sl_count(struct sortedlist *_list_) -{ - return _list_->count; -} -size_t sl_capacity(struct sortedlist *_list_) -{ - return _list_->capacity; -} -int sl_flag(struct sortedlist *_list_) -{ - return _list_->flag; -} -_Bool sl_resize(struct sortedlist *_list_, size_t capacity) -{ - if (_list_->capacity == capacity) - goto success; - if (capacity < _list_->count) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); - if (!new_buffer) - { - _list_->flag = CMC_FLAG_ALLOC; - return 0; - } - _list_->buffer = new_buffer; - _list_->capacity = capacity; -success: - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->resize) - (_list_)->callbacks->resize(); - ; - return 1; -} -void sl_sort(struct sortedlist *_list_) -{ - _list_->flag = CMC_FLAG_OK; - if (!_list_->is_sorted && _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, ((void *)0)); - if (!result) - { - _list_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _list_->callbacks; - if (_list_->f_val->cpy) - { - for (size_t i = 0; i < _list_->count; i++) - result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); - } - else - memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); - result->count = _list_->count; - _list_->flag = CMC_FLAG_OK; - return result; -} -_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_) -{ - if (_list1_->count != _list2_->count) - return 0; - sl_sort(_list1_); - sl_sort(_list2_); - for (size_t i = 0; i < _list1_->count; i++) - { - if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) - return 0; - } - return 1; -} -static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value) -{ - if (sl_empty(_list_)) - return 1; - size_t L = 0; - size_t R = _list_->count; - while (L < R) - { - size_t M = L + (R - L) / 2; - if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) - L = M + 1; - else - R = M; - } - if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) - return L; - return _list_->count; -} -static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value) -{ - if (sl_empty(_list_)) - return 1; - size_t L = 0; - size_t R = _list_->count; - while (L < R) - { - size_t M = L + (R - L) / 2; - if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) - R = M; - else - L = M + 1; - } - if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) - return L - 1; - return _list_->count; -} -void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) -{ - while (low < high) - { - if (high - low < 10) - { - sl_impl_sort_insertion(array, cmp, low, high); - break; - } - else - { - size_t pivot = array[high]; - size_t pindex = low; - for (size_t i = low; i < high; i++) - { - if (cmp(array[i], pivot) <= 0) - { - size_t _tmp_ = array[i]; - array[i] = array[pindex]; - array[pindex] = _tmp_; - pindex++; - } - } - size_t _tmp_ = array[pindex]; - array[pindex] = array[high]; - array[high] = _tmp_; - if (pindex - low < high - pindex) - { - sl_impl_sort_quicksort(array, cmp, low, pindex - 1); - low = pindex + 1; - } - else - { - sl_impl_sort_quicksort(array, cmp, pindex + 1, high); - high = pindex - 1; - } - } - } -} -void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) -{ - for (size_t i = low + 1; i <= high; i++) - { - size_t _tmp_ = array[i]; - size_t j = i; - while (j > low && cmp(array[j - 1], _tmp_) > 0) - { - array[j] = array[j - 1]; - j--; - } - array[j] = _tmp_; - } -} -struct sortedlist_iter sl_iter_start(struct sortedlist *target) -{ - sl_sort(target); - struct sortedlist_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = sl_empty(target); - return iter; -} -struct sortedlist_iter sl_iter_end(struct sortedlist *target) -{ - sl_sort(target); - struct sortedlist_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = sl_empty(target); - iter.end = 1; - if (!sl_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool sl_iter_at_start(struct sortedlist_iter *iter) -{ - return sl_empty(iter->target) || iter->start; -} -_Bool sl_iter_at_end(struct sortedlist_iter *iter) -{ - return sl_empty(iter->target) || iter->end; -} -_Bool sl_iter_to_start(struct sortedlist_iter *iter) -{ - if (!sl_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = sl_empty(iter->target); - return 1; - } - return 0; -} -_Bool sl_iter_to_end(struct sortedlist_iter *iter) -{ - if (!sl_empty(iter->target)) - { - iter->start = sl_empty(iter->target); - iter->cursor = iter->target->count - 1; - iter->end = 1; - return 1; - } - return 0; -} -_Bool sl_iter_next(struct sortedlist_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = sl_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool sl_iter_prev(struct sortedlist_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = sl_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - iter->start = sl_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = sl_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return sl_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return sl_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t sl_iter_value(struct sortedlist_iter *iter) -{ - if (sl_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t sl_iter_index(struct sortedlist_iter *iter) -{ - return iter->cursor; -} -_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr) -{ - struct sortedlist *l_ = _list_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "is_sorted:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count, - l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); -} -_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - sl_sort(_list_); - fprintf(fptr, "%s", start); - for (size_t i = 0; i < _list_->count; i++) - { - if (!_list_->f_val->str(fptr, _list_->buffer[i])) - return 0; - if (i + 1 < _list_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/stack.c b/tests/src/cmc/stack.c deleted file mode 100644 index 46cf798..0000000 --- a/tests/src/cmc/stack.c +++ /dev/null @@ -1,367 +0,0 @@ - -#include "cmc/stack.h" - -struct stack *s_new(size_t capacity, struct stack_fval *f_val) -{ - return s_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct stack *_stack_ = alloc->malloc(sizeof(struct stack)); - if (!_stack_) - return ((void *)0); - _stack_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_stack_->buffer) - { - alloc->free(_stack_); - return ((void *)0); - } - _stack_->capacity = capacity; - _stack_->count = 0; - _stack_->flag = CMC_FLAG_OK; - _stack_->f_val = f_val; - _stack_->alloc = alloc; - (_stack_)->callbacks = callbacks; - return _stack_; -} -void s_clear(struct stack *_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(size_t) * _stack_->capacity); - _stack_->count = 0; - _stack_->flag = CMC_FLAG_OK; -} -void s_free(struct stack *_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 s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _stack_->alloc = &cmc_alloc_node_default; - else - _stack_->alloc = alloc; - (_stack_)->callbacks = callbacks; - _stack_->flag = CMC_FLAG_OK; -} -_Bool s_push(struct stack *_stack_, size_t value) -{ - if (s_full(_stack_)) - { - if (!s_resize(_stack_, _stack_->capacity * 2)) - return 0; - } - _stack_->buffer[_stack_->count++] = value; - _stack_->flag = CMC_FLAG_OK; - if ((_stack_)->callbacks && (_stack_)->callbacks->create) - (_stack_)->callbacks->create(); - ; - return 1; -} -_Bool s_pop(struct stack *_stack_) -{ - if (s_empty(_stack_)) - { - _stack_->flag = CMC_FLAG_EMPTY; - return 0; - } - _stack_->buffer[--_stack_->count] = (size_t){ 0 }; - _stack_->flag = CMC_FLAG_OK; - if ((_stack_)->callbacks && (_stack_)->callbacks->delete) - (_stack_)->callbacks->delete (); - ; - return 1; -} -size_t s_top(struct stack *_stack_) -{ - if (s_empty(_stack_)) - { - _stack_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _stack_->flag = CMC_FLAG_OK; - if ((_stack_)->callbacks && (_stack_)->callbacks->read) - (_stack_)->callbacks->read(); - ; - return _stack_->buffer[_stack_->count - 1]; -} -_Bool s_contains(struct stack *_stack_, size_t value) -{ - _stack_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = 0; i < _stack_->count; i++) - { - if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) - { - result = 1; - break; - } - } - if ((_stack_)->callbacks && (_stack_)->callbacks->read) - (_stack_)->callbacks->read(); - ; - return result; -} -_Bool s_empty(struct stack *_stack_) -{ - return _stack_->count == 0; -} -_Bool s_full(struct stack *_stack_) -{ - return _stack_->count >= _stack_->capacity; -} -size_t s_count(struct stack *_stack_) -{ - return _stack_->count; -} -size_t s_capacity(struct stack *_stack_) -{ - return _stack_->capacity; -} -int s_flag(struct stack *_stack_) -{ - return _stack_->flag; -} -_Bool s_resize(struct stack *_stack_, size_t capacity) -{ - if (_stack_->capacity == capacity) - goto success; - if (capacity < _stack_->count) - { - _stack_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity); - if (!new_buffer) - { - _stack_->flag = CMC_FLAG_ALLOC; - return 0; - } - _stack_->buffer = new_buffer; - _stack_->capacity = capacity; -success: - _stack_->flag = CMC_FLAG_OK; - if ((_stack_)->callbacks && (_stack_)->callbacks->resize) - (_stack_)->callbacks->resize(); - ; - return 1; -} -struct stack *s_copy_of(struct stack *_stack_) -{ - struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0)); - if (!result) - { - _stack_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _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(size_t) * _stack_->count); - result->count = _stack_->count; - _stack_->flag = CMC_FLAG_OK; - return result; -} -_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_) -{ - _stack1_->flag = CMC_FLAG_OK; - _stack2_->flag = CMC_FLAG_OK; - if (_stack1_->count != _stack2_->count) - return 0; - for (size_t i = 0; i < _stack1_->count; i++) - { - if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) - return 0; - } - return 1; -} -struct stack_iter s_iter_start(struct stack *target) -{ - struct stack_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = s_empty(target); - if (!s_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -struct stack_iter s_iter_end(struct stack *target) -{ - struct stack_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = s_empty(target); - iter.end = 1; - return iter; -} -_Bool s_iter_at_start(struct stack_iter *iter) -{ - return s_empty(iter->target) || iter->start; -} -_Bool s_iter_at_end(struct stack_iter *iter) -{ - return s_empty(iter->target) || iter->end; -} -_Bool s_iter_to_start(struct stack_iter *iter) -{ - if (!s_empty(iter->target)) - { - iter->cursor = iter->target->count - 1; - iter->start = 1; - iter->end = s_empty(iter->target); - return 1; - } - return 0; -} -_Bool s_iter_to_end(struct stack_iter *iter) -{ - if (!s_empty(iter->target)) - { - iter->cursor = 0; - iter->start = s_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool s_iter_next(struct stack_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor == 0) - { - iter->end = 1; - return 0; - } - iter->start = s_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool s_iter_prev(struct stack_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->start = 1; - return 0; - } - iter->end = s_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool s_iter_advance(struct stack_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor == 0) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->start = s_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool s_iter_rewind(struct stack_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - iter->end = s_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool s_iter_go_to(struct stack_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return s_iter_advance(iter, iter->cursor - index); - else if (iter->cursor < index) - return s_iter_rewind(iter, index - iter->cursor); - return 1; -} -size_t s_iter_value(struct stack_iter *iter) -{ - if (s_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t *s_iter_rvalue(struct stack_iter *iter) -{ - if (s_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor]); -} -size_t s_iter_index(struct stack_iter *iter) -{ - if (s_empty(iter->target)) - return 0; - return iter->target->count - 1 - iter->cursor; -} -_Bool s_to_string(struct stack *_stack_, FILE *fptr) -{ - struct stack *s_ = _stack_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, - (s_)->callbacks); -} -_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = _stack_->count; i > 0; i--) - { - if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) - return 0; - if (i - 1 != 0) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/treemap.c b/tests/src/cmc/treemap.c deleted file mode 100644 index a019f9b..0000000 --- a/tests/src/cmc/treemap.c +++ /dev/null @@ -1,852 +0,0 @@ - -#include "cmc/treemap.h" - -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); -static void tm_impl_rotate_right(struct treemap_node **Z); -static void tm_impl_rotate_left(struct treemap_node **Z); -static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node); -struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val) -{ - return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0)); -} -struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (!f_key || !f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct treemap *_map_ = alloc->malloc(sizeof(struct treemap)); - if (!_map_) - return ((void *)0); - _map_->count = 0; - _map_->root = ((void *)0); - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - return _map_; -} -void tm_clear(struct treemap *_map_) -{ - struct treemap_node *scan = _map_->root; - struct treemap_node *up = ((void *)0); - while (scan != ((void *)0)) - { - if (scan->left != ((void *)0)) - { - struct treemap_node *left = scan->left; - scan->left = up; - up = scan; - scan = left; - } - else if (scan->right != ((void *)0)) - { - struct treemap_node *right = scan->right; - scan->left = up; - scan->right = ((void *)0); - up = scan; - scan = right; - } - else - { - if (up == ((void *)0)) - { - 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 = ((void *)0); - } - while (up != ((void *)0)) - { - 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 != ((void *)0)) - { - scan = up->right; - up->right = ((void *)0); - break; - } - else - { - scan = up; - up = up->left; - } - } - } - } - _map_->count = 0; - _map_->root = ((void *)0); - _map_->flag = CMC_FLAG_OK; -} -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) -{ - ; - if (!alloc) - _map_->alloc = &cmc_alloc_node_default; - else - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->flag = CMC_FLAG_OK; -} -_Bool tm_insert(struct treemap *_map_, size_t key, size_t value) -{ - if (tm_empty(_map_)) - { - _map_->root = tm_impl_new_node(_map_, key, value); - if (!_map_->root) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - } - else - { - struct treemap_node *scan = _map_->root; - struct treemap_node *parent = scan; - while (scan != ((void *)0)) - { - 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 0; - } - } - struct treemap_node *node; - if (_map_->f_key->cmp(parent->key, key) > 0) - { - parent->left = tm_impl_new_node(_map_, key, value); - if (!parent->left) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - parent->left->parent = parent; - node = parent->left; - } - else - { - parent->right = tm_impl_new_node(_map_, key, value); - if (!parent->right) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - parent->right->parent = parent; - node = parent->right; - } - tm_impl_rebalance(_map_, node); - } - _map_->count++; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->create) - (_map_)->callbacks->create(); - ; - return 1; -} -_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value) -{ - struct treemap_node *node = tm_impl_get_node(_map_, key); - if (!node) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - 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 1; -} -_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treemap_node *node = tm_impl_get_node(_map_, key); - if (!node) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (out_value) - *out_value = node->value; - struct treemap_node *temp = ((void *)0), *unbalanced = ((void *)0); - _Bool is_root = node->parent == ((void *)0); - if (node->left == ((void *)0) && node->right == ((void *)0)) - { - if (is_root) - _map_->root = ((void *)0); - else - { - unbalanced = node->parent; - if (node->parent->right == node) - node->parent->right = ((void *)0); - else - node->parent->left = ((void *)0); - } - _map_->alloc->free(node); - } - else if (node->left == ((void *)0)) - { - if (is_root) - { - _map_->root = node->right; - _map_->root->parent = ((void *)0); - } - 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 == ((void *)0)) - { - if (is_root) - { - _map_->root = node->left; - _map_->root->parent = ((void *)0); - } - 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 != ((void *)0)) - temp = temp->left; - size_t temp_key = temp->key; - size_t temp_val = temp->value; - unbalanced = temp->parent; - if (temp->left == ((void *)0) && temp->right == ((void *)0)) - { - if (temp->parent->right == temp) - temp->parent->right = ((void *)0); - else - temp->parent->left = ((void *)0); - } - else if (temp->left == ((void *)0)) - { - 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 == ((void *)0)) - { - 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 != ((void *)0)) - tm_impl_rebalance(_map_, unbalanced); - if (_map_->count == 0) - _map_->root = ((void *)0); - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treemap_node *scan = _map_->root; - while (scan->right != ((void *)0)) - 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 1; -} -_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treemap_node *scan = _map_->root; - while (scan->left != ((void *)0)) - 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 1; -} -size_t tm_get(struct treemap *_map_, size_t key) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - struct treemap_node *node = tm_impl_get_node(_map_, key); - if (!node) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return node->value; -} -size_t *tm_get_ref(struct treemap *_map_, size_t key) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - struct treemap_node *node = tm_impl_get_node(_map_, key); - if (!node) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return ((void *)0); - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return &(node->value); -} -_Bool tm_contains(struct treemap *_map_, size_t key) -{ - _Bool result = tm_impl_get_node(_map_, key) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool tm_empty(struct treemap *_map_) -{ - return _map_->count == 0; -} -size_t tm_count(struct treemap *_map_) -{ - return _map_->count; -} -int tm_flag(struct treemap *_map_) -{ - return _map_->flag; -} -struct treemap *tm_copy_of(struct treemap *_map_) -{ - struct treemap *result = tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); - if (!result) - { - _map_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - struct treemap_node *root = _map_->root; - _Bool left_done = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - size_t key; - size_t value; - if (_map_->f_key->cpy) - key = _map_->f_key->cpy(root->key); - else - key = root->key; - if (_map_->f_val->cpy) - value = _map_->f_val->cpy(root->value); - else - value = root->value; - tm_insert(result, key, value); - 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; - } - _map_->flag = CMC_FLAG_OK; - (result)->callbacks = _map_->callbacks; - return result; -} -_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) -{ - _map1_->flag = CMC_FLAG_OK; - _map2_->flag = CMC_FLAG_OK; - if (_map1_->count != _map2_->count) - return 0; - struct treemap_node *root = _map1_->root; - _Bool left_done = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - struct treemap_node *node = tm_impl_get_node(_map2_, root->key); - if (node == ((void *)0)) - return 0; - if (_map1_->f_val->cmp(node->value, root->value) != 0) - 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; -} -static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value) -{ - struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); - if (!node) - return ((void *)0); - node->key = key; - node->value = value; - node->right = ((void *)0); - node->left = ((void *)0); - node->parent = ((void *)0); - node->height = 0; - return node; -} -static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key) -{ - struct treemap_node *scan = _map_->root; - while (scan != ((void *)0)) - { - if (_map_->f_key->cmp(scan->key, key) > 0) - scan = scan->left; - else if (_map_->f_key->cmp(scan->key, key) < 0) - scan = scan->right; - else - return scan; - } - return ((void *)0); -} -static unsigned char tm_impl_h(struct treemap_node *node) -{ - if (node == ((void *)0)) - return 0; - return node->height; -} -static unsigned char tm_impl_hupdate(struct treemap_node *node) -{ - if (node == ((void *)0)) - return 0; - unsigned char h_l = tm_impl_h(node->left); - unsigned char h_r = tm_impl_h(node->right); - return 1 + (h_l > h_r ? h_l : h_r); -} -static void tm_impl_rotate_right(struct treemap_node **Z) -{ - struct treemap_node *root = *Z; - struct treemap_node *new_root = root->left; - if (root->parent != ((void *)0)) - { - if (root->parent->left == root) - root->parent->left = new_root; - else - root->parent->right = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->left = new_root->right; - if (root->left) - root->left->parent = root; - new_root->right = root; - root->height = tm_impl_hupdate(root); - new_root->height = tm_impl_hupdate(new_root); - *Z = new_root; -} -static void tm_impl_rotate_left(struct treemap_node **Z) -{ - struct treemap_node *root = *Z; - struct treemap_node *new_root = root->right; - if (root->parent != ((void *)0)) - { - if (root->parent->right == root) - root->parent->right = new_root; - else - root->parent->left = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->right = new_root->left; - if (root->right) - root->right->parent = root; - new_root->left = root; - root->height = tm_impl_hupdate(root); - new_root->height = tm_impl_hupdate(new_root); - *Z = new_root; -} -static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node) -{ - struct treemap_node *scan = node, *child = ((void *)0); - int balance; - _Bool is_root = 0; - while (scan != ((void *)0)) - { - if (scan->parent == ((void *)0)) - is_root = 1; - scan->height = tm_impl_hupdate(scan); - balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); - if (balance >= 2) - { - child = scan->right; - if (tm_impl_h(child->right) < tm_impl_h(child->left)) - tm_impl_rotate_right(&(scan->right)); - tm_impl_rotate_left(&scan); - } - else if (balance <= -2) - { - child = scan->left; - if (tm_impl_h(child->left) < tm_impl_h(child->right)) - tm_impl_rotate_left(&(scan->left)); - tm_impl_rotate_right(&scan); - } - if (is_root) - { - _map_->root = scan; - is_root = 0; - } - scan = scan->parent; - } -} -struct treemap_iter tm_iter_start(struct treemap *target) -{ - struct treemap_iter iter; - iter.target = target; - iter.cursor = target->root; - iter.first = ((void *)0); - iter.last = ((void *)0); - iter.index = 0; - iter.start = 1; - iter.end = tm_empty(target); - if (!tm_empty(target)) - { - while (iter.cursor->left != ((void *)0)) - iter.cursor = iter.cursor->left; - iter.first = iter.cursor; - iter.last = target->root; - while (iter.last->right != ((void *)0)) - iter.last = iter.last->right; - } - return iter; -} -struct treemap_iter tm_iter_end(struct treemap *target) -{ - struct treemap_iter iter; - iter.target = target; - iter.cursor = target->root; - iter.first = ((void *)0); - iter.last = ((void *)0); - iter.index = 0; - iter.start = tm_empty(target); - iter.end = 1; - if (!tm_empty(target)) - { - while (iter.cursor->right != ((void *)0)) - iter.cursor = iter.cursor->right; - iter.last = iter.cursor; - iter.first = target->root; - while (iter.first->left != ((void *)0)) - iter.first = iter.first->left; - iter.index = target->count - 1; - } - return iter; -} -_Bool tm_iter_at_start(struct treemap_iter *iter) -{ - return tm_empty(iter->target) || iter->start; -} -_Bool tm_iter_at_end(struct treemap_iter *iter) -{ - return tm_empty(iter->target) || iter->end; -} -_Bool tm_iter_to_start(struct treemap_iter *iter) -{ - if (!tm_empty(iter->target)) - { - iter->index = 0; - iter->start = 1; - iter->end = tm_empty(iter->target); - iter->cursor = iter->first; - return 1; - } - return 0; -} -_Bool tm_iter_to_end(struct treemap_iter *iter) -{ - if (!tm_empty(iter->target)) - { - iter->index = iter->target->count - 1; - iter->start = tm_empty(iter->target); - iter->end = 1; - iter->cursor = iter->last; - return 1; - } - return 0; -} -_Bool tm_iter_next(struct treemap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - iter->start = tm_empty(iter->target); - if (iter->cursor->right != ((void *)0)) - { - iter->cursor = iter->cursor->right; - while (iter->cursor->left != ((void *)0)) - iter->cursor = iter->cursor->left; - iter->index++; - return 1; - } - while (1) - { - if (iter->cursor->parent->left == iter->cursor) - { - iter->cursor = iter->cursor->parent; - iter->index++; - return 1; - } - iter->cursor = iter->cursor->parent; - } -} -_Bool tm_iter_prev(struct treemap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - iter->end = tm_empty(iter->target); - if (iter->cursor->left != ((void *)0)) - { - iter->cursor = iter->cursor->left; - while (iter->cursor->right != ((void *)0)) - iter->cursor = iter->cursor->right; - iter->index--; - return 1; - } - while (1) - { - if (iter->cursor->parent->right == iter->cursor) - { - iter->cursor = iter->cursor->parent; - iter->index--; - return 1; - } - iter->cursor = iter->cursor->parent; - } -} -_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - tm_iter_next(iter); - return 1; -} -_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - tm_iter_prev(iter); - return 1; -} -_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return tm_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return tm_iter_advance(iter, index - iter->index); - return 1; -} -size_t tm_iter_key(struct treemap_iter *iter) -{ - if (tm_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->key; -} -size_t tm_iter_value(struct treemap_iter *iter) -{ - if (tm_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->value; -} -size_t *tm_iter_rvalue(struct treemap_iter *iter) -{ - if (tm_empty(iter->target)) - return ((void *)0); - return &(iter->cursor->value); -} -size_t tm_iter_index(struct treemap_iter *iter) -{ - return iter->index; -} -_Bool tm_to_string(struct treemap *_map_, FILE *fptr) -{ - struct treemap *m_ = _map_; - return 0 <= fprintf(fptr, - "struct %s<%s, %s> " - "at %p { " - "root:%p, " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "f_key:%p, " - "alloc:%p, " - "callbacks:%p }", - "treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, - m_->alloc, (m_)->callbacks); -} -_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep) -{ - fprintf(fptr, "%s", start); - struct treemap_node *root = _map_->root; - _Bool left_done = 0; - size_t i = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - if (!_map_->f_key->str(fptr, root->key)) - return 0; - fprintf(fptr, "%s", key_val_sep); - if (!_map_->f_val->str(fptr, root->value)) - return 0; - if (++i < _map_->count) - fprintf(fptr, "%s", separator); - left_done = 1; - if (root->right) - { - left_done = 0; - root = root->right; - } - else if (root->parent) - { - while (root->parent && root == root->parent->right) - root = root->parent; - if (!root->parent) - break; - root = root->parent; - } - else - break; - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/cmc/treeset.c b/tests/src/cmc/treeset.c deleted file mode 100644 index 5216b54..0000000 --- a/tests/src/cmc/treeset.c +++ /dev/null @@ -1,841 +0,0 @@ - -#include "cmc/treeset.h" - -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); -static void ts_impl_rotate_left(struct treeset_node **Z); -static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node); -struct treeset *ts_new(struct treeset_fval *f_val) -{ - return ts_new_custom(f_val, ((void *)0), ((void *)0)); -} -struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct treeset *_set_ = alloc->malloc(sizeof(struct treeset)); - if (!_set_) - return ((void *)0); - _set_->count = 0; - _set_->root = ((void *)0); - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - return _set_; -} -void ts_clear(struct treeset *_set_) -{ - struct treeset_node *scan = _set_->root; - struct treeset_node *up = ((void *)0); - while (scan != ((void *)0)) - { - if (scan->left != ((void *)0)) - { - struct treeset_node *left = scan->left; - scan->left = up; - up = scan; - scan = left; - } - else if (scan->right != ((void *)0)) - { - struct treeset_node *right = scan->right; - scan->left = up; - scan->right = ((void *)0); - up = scan; - scan = right; - } - else - { - if (up == ((void *)0)) - { - if (_set_->f_val->free) - _set_->f_val->free(scan->value); - _set_->alloc->free(scan); - scan = ((void *)0); - } - while (up != ((void *)0)) - { - if (_set_->f_val->free) - _set_->f_val->free(scan->value); - _set_->alloc->free(scan); - if (up->right != ((void *)0)) - { - scan = up->right; - up->right = ((void *)0); - break; - } - else - { - scan = up; - up = up->left; - } - } - } - } - _set_->count = 0; - _set_->root = ((void *)0); - _set_->flag = CMC_FLAG_OK; -} -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) -{ - ; - if (!alloc) - _set_->alloc = &cmc_alloc_node_default; - else - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - _set_->flag = CMC_FLAG_OK; -} -_Bool ts_insert(struct treeset *_set_, size_t value) -{ - if (ts_empty(_set_)) - { - _set_->root = ts_impl_new_node(_set_, value); - if (!_set_->root) - { - _set_->flag = CMC_FLAG_ALLOC; - return 0; - } - } - else - { - struct treeset_node *scan = _set_->root; - struct treeset_node *parent = scan; - while (scan != ((void *)0)) - { - 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 0; - } - } - struct treeset_node *node; - if (_set_->f_val->cmp(parent->value, value) > 0) - { - parent->left = ts_impl_new_node(_set_, value); - if (!parent->left) - { - _set_->flag = CMC_FLAG_ALLOC; - return 0; - } - parent->left->parent = parent; - node = parent->left; - } - else - { - parent->right = ts_impl_new_node(_set_, value); - if (!parent->right) - { - _set_->flag = CMC_FLAG_ALLOC; - return 0; - } - parent->right->parent = parent; - node = parent->right; - } - ts_impl_rebalance(_set_, node); - } - _set_->count++; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->create) - (_set_)->callbacks->create(); - ; - return 1; -} -_Bool ts_remove(struct treeset *_set_, size_t value) -{ - if (ts_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treeset_node *node = ts_impl_get_node(_set_, value); - if (!node) - { - _set_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - struct treeset_node *temp = ((void *)0), *unbalanced = ((void *)0); - _Bool is_root = node->parent == ((void *)0); - if (node->left == ((void *)0) && node->right == ((void *)0)) - { - if (is_root) - _set_->root = ((void *)0); - else - { - unbalanced = node->parent; - if (node->parent->right == node) - node->parent->right = ((void *)0); - else - node->parent->left = ((void *)0); - } - _set_->alloc->free(node); - } - else if (node->left == ((void *)0)) - { - if (is_root) - { - _set_->root = node->right; - _set_->root->parent = ((void *)0); - } - 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 == ((void *)0)) - { - if (is_root) - { - _set_->root = node->left; - _set_->root->parent = ((void *)0); - } - 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 != ((void *)0)) - temp = temp->left; - size_t temp_value = temp->value; - unbalanced = temp->parent; - if (temp->left == ((void *)0) && temp->right == ((void *)0)) - { - if (temp->parent->right == temp) - temp->parent->right = ((void *)0); - else - temp->parent->left = ((void *)0); - } - else if (temp->left == ((void *)0)) - { - 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 == ((void *)0)) - { - 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 != ((void *)0)) - ts_impl_rebalance(_set_, unbalanced); - if (_set_->count == 0) - _set_->root = ((void *)0); - _set_->count--; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->delete) - (_set_)->callbacks->delete (); - ; - return 1; -} -_Bool ts_max(struct treeset *_set_, size_t *value) -{ - if (ts_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treeset_node *scan = _set_->root; - while (scan->right != ((void *)0)) - scan = scan->right; - if (value) - *value = scan->value; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool ts_min(struct treeset *_set_, size_t *value) -{ - if (ts_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treeset_node *scan = _set_->root; - while (scan->left != ((void *)0)) - scan = scan->left; - if (value) - *value = scan->value; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool ts_contains(struct treeset *_set_, size_t value) -{ - _Bool result = ts_impl_get_node(_set_, value) != ((void *)0); - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return result; -} -_Bool ts_empty(struct treeset *_set_) -{ - return _set_->count == 0; -} -size_t ts_count(struct treeset *_set_) -{ - return _set_->count; -} -int ts_flag(struct treeset *_set_) -{ - return _set_->flag; -} -struct treeset *ts_copy_of(struct treeset *_set_) -{ - struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0)); - if (!result) - { - _set_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _set_->callbacks; - if (!ts_empty(_set_)) - { - struct treeset_iter iter = ts_iter_start(_set_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - if (_set_->f_val->cpy) - ts_insert(result, _set_->f_val->cpy(ts_iter_value(&iter))); - else - ts_insert(result, ts_iter_value(&iter)); - } - } - _set_->flag = CMC_FLAG_OK; - return result; -} -_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count != _set2_->count) - return 0; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - if (ts_impl_get_node(_set2_, ts_iter_value(&iter)) == ((void *)0)) - return 0; - } - return 1; -} -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)); - if (!node) - return ((void *)0); - node->value = value; - node->right = ((void *)0); - node->left = ((void *)0); - node->parent = ((void *)0); - node->height = 0; - return node; -} -static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value) -{ - struct treeset_node *scan = _set_->root; - while (scan != ((void *)0)) - { - 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 ((void *)0); -} -static unsigned char ts_impl_h(struct treeset_node *node) -{ - if (node == ((void *)0)) - return 0; - return node->height; -} -static unsigned char ts_impl_hupdate(struct treeset_node *node) -{ - if (node == ((void *)0)) - return 0; - unsigned char h_l = ts_impl_h(node->left); - unsigned char h_r = ts_impl_h(node->right); - return 1 + (h_l > h_r ? h_l : h_r); -} -static void ts_impl_rotate_right(struct treeset_node **Z) -{ - struct treeset_node *root = *Z; - struct treeset_node *new_root = root->left; - if (root->parent != ((void *)0)) - { - if (root->parent->left == root) - root->parent->left = new_root; - else - root->parent->right = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->left = new_root->right; - if (root->left) - root->left->parent = root; - new_root->right = root; - root->height = ts_impl_hupdate(root); - new_root->height = ts_impl_hupdate(new_root); - *Z = new_root; -} -static void ts_impl_rotate_left(struct treeset_node **Z) -{ - struct treeset_node *root = *Z; - struct treeset_node *new_root = root->right; - if (root->parent != ((void *)0)) - { - if (root->parent->right == root) - root->parent->right = new_root; - else - root->parent->left = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->right = new_root->left; - if (root->right) - root->right->parent = root; - new_root->left = root; - root->height = ts_impl_hupdate(root); - new_root->height = ts_impl_hupdate(new_root); - *Z = new_root; -} -static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) -{ - struct treeset_node *scan = node, *child = ((void *)0); - int balance; - _Bool is_root = 0; - while (scan != ((void *)0)) - { - if (scan->parent == ((void *)0)) - is_root = 1; - scan->height = ts_impl_hupdate(scan); - balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); - if (balance >= 2) - { - child = scan->right; - if (ts_impl_h(child->right) < ts_impl_h(child->left)) - ts_impl_rotate_right(&(scan->right)); - ts_impl_rotate_left(&scan); - } - else if (balance <= -2) - { - child = scan->left; - if (ts_impl_h(child->left) < ts_impl_h(child->right)) - ts_impl_rotate_left(&(scan->left)); - ts_impl_rotate_right(&scan); - } - if (is_root) - { - _set_->root = scan; - is_root = 0; - } - scan = scan->parent; - } -} -struct treeset_iter ts_iter_start(struct treeset *target) -{ - struct treeset_iter iter; - iter.target = target; - iter.cursor = target->root; - iter.first = ((void *)0); - iter.last = ((void *)0); - iter.index = 0; - iter.start = 1; - iter.end = ts_empty(target); - if (!ts_empty(target)) - { - while (iter.cursor->left != ((void *)0)) - iter.cursor = iter.cursor->left; - iter.first = iter.cursor; - iter.last = target->root; - while (iter.last->right != ((void *)0)) - iter.last = iter.last->right; - } - return iter; -} -struct treeset_iter ts_iter_end(struct treeset *target) -{ - struct treeset_iter iter; - iter.target = target; - iter.cursor = target->root; - iter.first = ((void *)0); - iter.last = ((void *)0); - iter.index = 0; - iter.start = ts_empty(target); - iter.end = 1; - if (!ts_empty(target)) - { - while (iter.cursor->right != ((void *)0)) - iter.cursor = iter.cursor->right; - iter.last = iter.cursor; - iter.first = target->root; - while (iter.first->left != ((void *)0)) - iter.first = iter.first->left; - iter.index = target->count - 1; - } - return iter; -} -_Bool ts_iter_at_start(struct treeset_iter *iter) -{ - return ts_empty(iter->target) || iter->start; -} -_Bool ts_iter_at_end(struct treeset_iter *iter) -{ - return ts_empty(iter->target) || iter->end; -} -_Bool ts_iter_to_start(struct treeset_iter *iter) -{ - if (!ts_empty(iter->target)) - { - iter->index = 0; - iter->start = 1; - iter->end = ts_empty(iter->target); - iter->cursor = iter->first; - return 1; - } - return 0; -} -_Bool ts_iter_to_end(struct treeset_iter *iter) -{ - if (!ts_empty(iter->target)) - { - iter->index = iter->target->count - 1; - iter->start = ts_empty(iter->target); - iter->end = 1; - iter->cursor = iter->last; - return 1; - } - return 0; -} -_Bool ts_iter_next(struct treeset_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - iter->start = ts_empty(iter->target); - if (iter->cursor->right != ((void *)0)) - { - iter->cursor = iter->cursor->right; - while (iter->cursor->left != ((void *)0)) - iter->cursor = iter->cursor->left; - iter->index++; - return 1; - } - while (1) - { - if (iter->cursor->parent->left == iter->cursor) - { - iter->cursor = iter->cursor->parent; - iter->index++; - return 1; - } - iter->cursor = iter->cursor->parent; - } -} -_Bool ts_iter_prev(struct treeset_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - iter->end = ts_empty(iter->target); - if (iter->cursor->left != ((void *)0)) - { - iter->cursor = iter->cursor->left; - while (iter->cursor->right != ((void *)0)) - iter->cursor = iter->cursor->right; - iter->index--; - return 1; - } - while (1) - { - if (iter->cursor->parent->right == iter->cursor) - { - iter->cursor = iter->cursor->parent; - iter->index--; - return 1; - } - iter->cursor = iter->cursor->parent; - } -} -_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - ts_iter_next(iter); - return 1; -} -_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - ts_iter_prev(iter); - return 1; -} -_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return ts_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return ts_iter_advance(iter, index - iter->index); - return 1; -} -size_t ts_iter_value(struct treeset_iter *iter) -{ - if (ts_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->value; -} -size_t ts_iter_index(struct treeset_iter *iter) -{ - return iter->index; -} -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter1 = ts_iter_start(_set1_); - struct treeset_iter iter2 = ts_iter_start(_set2_); - for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) - { - ts_insert(_set_r_, ts_iter_value(&iter1)); - } - for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) - { - ts_insert(_set_r_, ts_iter_value(&iter2)); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct treeset_iter iter = ts_iter_start(_set_A_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set_B_, value) != ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter1 = ts_iter_start(_set1_); - struct treeset_iter iter2 = ts_iter_start(_set2_); - for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) - { - size_t value = ts_iter_value(&iter1); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) - { - size_t value = ts_iter_value(&iter2); - if (ts_impl_get_node(_set1_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (_set1_->count > _set2_->count) - return 0; - if (ts_empty(_set1_)) - return 1; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_) -{ - return ts_is_subset(_set2_, _set1_); -} -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (_set1_->count >= _set2_->count) - return 0; - if (ts_empty(_set1_)) - { - if (!ts_empty(_set2_)) - return 1; - else - return 0; - } - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_) -{ - return ts_is_proper_subset(_set2_, _set1_); -} -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (ts_empty(_set1_)) - return 1; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) != ((void *)0)) - return 0; - } - return 1; -} -_Bool ts_to_string(struct treeset *_set_, FILE *fptr) -{ - struct treeset *s_ = _set_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "root:%p, " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); -} -_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - struct treeset_node *root = _set_->root; - _Bool left_done = 0; - size_t i = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - if (!_set_->f_val->str(fptr, root->value)) - return 0; - if (++i < _set_->count) - fprintf(fptr, "%s", separator); - left_done = 1; - if (root->right) - { - left_done = 0; - root = root->right; - } - else if (root->parent) - { - while (root->parent && root == root->parent->right) - root = root->parent; - if (!root->parent) - break; - root = root->parent; - } - else - break; - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_bitset.c b/tests/src/tst_cmc_bitset.c new file mode 100644 index 0000000..b995c83 --- /dev/null +++ b/tests/src/tst_cmc_bitset.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_bitset.h" + + + _Bool bs_impl_resize(struct bitset * _bitset_, size_t n_bits, _Bool do_resize); 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) { ; if (n_bits < 1) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset)); if (!_bitset_) return ((void *)0); _bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); if (!_bitset_->buffer) { alloc->free(_bitset_); return ((void *)0); } _bitset_->capacity = capacity; _bitset_->flag = CMC_FLAG_OK; _bitset_->alloc = alloc; (_bitset_)->callbacks = callbacks; return _bitset_; } struct bitset bs_init(size_t n_bits) { return bs_init_custom(n_bits, ((void *)0), ((void *)0)); } struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node * alloc, struct cmc_callbacks * __attribute__((__unused__))(callbacks)) { ; struct bitset _bitset_ = { 0 }; if (n_bits < 1) return _bitset_; if (!alloc) alloc = &cmc_alloc_node_default; size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); if (!_bitset_.buffer) return _bitset_; _bitset_.capacity = capacity; _bitset_.flag = CMC_FLAG_OK; _bitset_.alloc = alloc; (&_bitset_)->callbacks = callbacks; return _bitset_; } void bs_free(struct bitset * _bitset_) { free(_bitset_->buffer); free(_bitset_); } void bs_release(struct bitset _bitset_) { free(_bitset_.buffer); } void bs_customize(struct bitset * _bitset_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _bitset_->alloc = &cmc_alloc_node_default; else _bitset_->alloc = alloc; (_bitset_)->callbacks = callbacks; _bitset_->flag = CMC_FLAG_OK; } _Bool bs_set(struct bitset * _bitset_, size_t bit_index) { if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) (_bitset_)->callbacks->create();; return 1; } _Bool bs_set_range(struct bitset * _bitset_, size_t from, size_t to) { if (to < from) { _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; size_t start_index = cmc_bidx_to_widx(from); size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; 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 1; } _Bool bs_clear(struct bitset * _bitset_, size_t bit_index) { if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) (_bitset_)->callbacks->delete();; return 1; } _Bool bs_clear_range(struct bitset * _bitset_, size_t from, size_t to) { if (to < from) { _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; size_t start_index = cmc_bidx_to_widx(from); size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; 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 1; } _Bool bs_flip(struct bitset * _bitset_, size_t bit_index) { if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) (_bitset_)->callbacks->update();; return 1; } _Bool bs_flip_range(struct bitset * _bitset_, size_t from, size_t to) { if (to < from) { _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; size_t start_index = cmc_bidx_to_widx(from); size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; 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 1; } _Bool bs_put(struct bitset * _bitset_, size_t bit_index, _Bool state) { if (state) return bs_set(_bitset_, bit_index); else return bs_clear(_bitset_, bit_index); } _Bool bs_put_range(struct bitset * _bitset_, size_t from, size_t to, _Bool state) { if (state) return bs_set_range(_bitset_, from, to); else return bs_clear_range(_bitset_, from, to); } _Bool bs_set_all(struct bitset * _bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = ~((cmc_bitset_word)0); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) (_bitset_)->callbacks->create();; return 1; } _Bool bs_clear_all(struct bitset * _bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = 0; _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) (_bitset_)->callbacks->delete();; return 1; } _Bool bs_flip_all(struct bitset * _bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) (_bitset_)->callbacks->create();; return 1; } _Bool bs_get(struct bitset * _bitset_, size_t bit_index) { const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; return w & ((cmc_bitset_word)1 << (bit_index % bits)); } _Bool bs_resize(struct bitset * _bitset_, size_t n_bits) { return bs_impl_resize(_bitset_, n_bits, 1); } _Bool bs_impl_resize(struct bitset * _bitset_, size_t n_bits, _Bool do_resize) { if (n_bits == 0) { _bitset_->flag = CMC_FLAG_INVALID; return 0; } size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; if (!do_resize && words <= _bitset_->capacity) return 1; cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); if (!new_buffer) { _bitset_->flag = CMC_FLAG_ALLOC; return 0; } _bitset_->buffer = new_buffer; 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 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_deque.c b/tests/src/tst_cmc_deque.c new file mode 100644 index 0000000..e67e9d7 --- /dev/null +++ b/tests/src/tst_cmc_deque.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_deque.h" + + + 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 cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct deque *_deque_ = alloc->malloc(sizeof(struct deque)); if (!_deque_) return ((void *)0); _deque_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_deque_->buffer) { alloc->free(_deque_); return ((void *)0); } _deque_->capacity = capacity; _deque_->count = 0; _deque_->front = 0; _deque_->back = 0; _deque_->flag = CMC_FLAG_OK; _deque_->f_val = f_val; _deque_->alloc = alloc; (_deque_)->callbacks = callbacks; return _deque_; } void d_clear(struct deque * _deque_) { if (_deque_->f_val->free) { for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { _deque_->f_val->free(_deque_->buffer[i]); i = (i + 1) % _deque_->capacity; } } memset(_deque_->buffer, 0, sizeof(size_t) * _deque_->capacity); _deque_->count = 0; _deque_->front = 0; _deque_->back = 0; _deque_->flag = CMC_FLAG_OK; } void d_free(struct deque * _deque_) { if (_deque_->f_val->free) { for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { _deque_->f_val->free(_deque_->buffer[i]); i = (i + 1) % _deque_->capacity; } } _deque_->alloc->free(_deque_->buffer); _deque_->alloc->free(_deque_); } void d_customize(struct deque * _deque_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _deque_->alloc = &cmc_alloc_node_default; else _deque_->alloc = alloc; (_deque_)->callbacks = callbacks; _deque_->flag = CMC_FLAG_OK; } _Bool d_push_front(struct deque * _deque_, size_t value) { if (d_full(_deque_)) { if (!d_resize(_deque_, _deque_->capacity * 2)) return 0; } _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 1; } _Bool d_push_back(struct deque * _deque_, size_t value) { if (d_full(_deque_)) { if (!d_resize(_deque_, _deque_->capacity * 2)) return 0; } _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 1; } _Bool d_pop_front(struct deque * _deque_) { if (d_empty(_deque_)) { _deque_->flag = CMC_FLAG_EMPTY; return 0; } _deque_->buffer[_deque_->front] = (size_t){ 0 }; _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; _deque_->count--; _deque_->flag = CMC_FLAG_OK; if ((_deque_)->callbacks && (_deque_)->callbacks->delete) (_deque_)->callbacks->delete();; return 1; } _Bool d_pop_back(struct deque * _deque_) { if (d_empty(_deque_)) { _deque_->flag = CMC_FLAG_EMPTY; return 0; } _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; _deque_->buffer[_deque_->back] = (size_t){ 0 }; _deque_->count--; _deque_->flag = CMC_FLAG_OK; if ((_deque_)->callbacks && (_deque_)->callbacks->delete) (_deque_)->callbacks->delete();; return 1; } size_t d_front(struct deque * _deque_) { if (d_empty(_deque_)) { _deque_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _deque_->flag = CMC_FLAG_OK; if ((_deque_)->callbacks && (_deque_)->callbacks->read) (_deque_)->callbacks->read();; return _deque_->buffer[_deque_->front]; } size_t d_back(struct deque * _deque_) { if (d_empty(_deque_)) { _deque_->flag = CMC_FLAG_EMPTY; return (size_t){ 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 d_contains(struct deque * _deque_, size_t value) { _deque_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) { result = 1; break; } i = (i + 1) % _deque_->capacity; } if ((_deque_)->callbacks && (_deque_)->callbacks->read) (_deque_)->callbacks->read();; return result; } _Bool d_empty(struct deque * _deque_) { return _deque_->count == 0; } _Bool d_full(struct deque * _deque_) { return _deque_->count >= _deque_->capacity; } size_t d_count(struct deque * _deque_) { return _deque_->count; } size_t d_capacity(struct deque * _deque_) { return _deque_->capacity; } int d_flag(struct deque * _deque_) { return _deque_->flag; } _Bool d_resize(struct deque * _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 0; } size_t *new_buffer = _deque_->alloc->malloc(sizeof(size_t) * capacity); if (!new_buffer) { _deque_->flag = CMC_FLAG_ALLOC; return 0; } 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 1; } struct deque *d_copy_of(struct deque * _deque_) { struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0)); if (!result) { _deque_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _deque_->callbacks; if (_deque_->f_val->cpy) { for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { 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 d_equals(struct deque * _deque1_, struct deque * _deque2_) { _deque1_->flag = CMC_FLAG_OK; _deque2_->flag = CMC_FLAG_OK; 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++) { if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) return 0; i = (i + 1) % _deque1_->capacity; j = (j + 1) % _deque2_->capacity; } return 1; } struct deque d_init(size_t capacity, struct deque_fval * f_val) { return d_init_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct deque d_init_custom(size_t capacity, struct deque_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; struct deque _deque_ = { 0 }; if (capacity < 1) return _deque_; if (!f_val) return _deque_; if (!alloc) alloc = &cmc_alloc_node_default; _deque_.buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_deque_.buffer) return _deque_; _deque_.capacity = capacity; _deque_.count = 0; _deque_.front = 0; _deque_.back = 0; _deque_.flag = CMC_FLAG_OK; _deque_.f_val = f_val; _deque_.alloc = alloc; (&_deque_)->callbacks = callbacks; return _deque_; } void d_release(struct deque _deque_) { if (_deque_.f_val->free) { for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) { _deque_.f_val->free(_deque_.buffer[i]); i = (i + 1) % _deque_.capacity; } } _deque_.alloc->free(_deque_.buffer); } struct deque_iter d_iter_start(struct deque * target) { struct deque_iter iter; iter.target = target; iter.cursor = target->front; iter.index = 0; iter.start = 1; iter.end = d_empty(target); return iter; } struct deque_iter d_iter_end(struct deque * target) { struct deque_iter iter; iter.target = target; if (!d_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 = d_empty(target); iter.end = 1; return iter; } _Bool d_iter_at_start(struct deque_iter * iter) { return d_empty(iter->target) || iter->start; } _Bool d_iter_at_end(struct deque_iter * iter) { return d_empty(iter->target) || iter->end; } _Bool d_iter_to_start(struct deque_iter * iter) { if (!d_empty(iter->target)) { iter->cursor = iter->target->front; iter->index = 0; iter->start = 1; iter->end = 0; return 1; } return 0; } _Bool d_iter_to_end(struct deque_iter * iter) { if (!d_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 = 0; iter->end = 1; return 1; } return 0; } _Bool d_iter_next(struct deque_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = d_empty(iter->target); iter->cursor = (iter->cursor + 1) % (iter->target->capacity); iter->index++; return 1; } _Bool d_iter_prev(struct deque_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = d_empty(iter->target); iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; iter->index--; return 1; } _Bool d_iter_advance(struct deque_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; iter->start = d_empty(iter->target); iter->index += steps; iter->cursor = (iter->cursor + steps) % iter->target->capacity; return 1; } _Bool d_iter_rewind(struct deque_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; iter->end = d_empty(iter->target); iter->index -= steps; if (iter->cursor < steps) iter->cursor += iter->target->capacity; iter->cursor -= steps; return 1; } _Bool d_iter_go_to(struct deque_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return d_iter_rewind(iter, iter->index - index); else if (iter->index < index) return d_iter_advance(iter, index - iter->index); return 1; } size_t d_iter_value(struct deque_iter * iter) { if (d_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t *d_iter_rvalue(struct deque_iter * iter) { if (d_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor]); } size_t d_iter_index(struct deque_iter * iter) { return iter->index; } _Bool d_to_string(struct deque * _deque_, FILE * fptr) { struct deque *d_ = _deque_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "front:%" "I64u" ", " "back:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag, d_->f_val, d_->alloc, (d_)->callbacks); } _Bool d_print(struct deque * _deque_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) return 0; i = (i + 1) % _deque_->capacity; if (j + 1 < _deque_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_hashbidimap.c b/tests/src/tst_cmc_hashbidimap.c new file mode 100644 index 0000000..8b46a90 --- /dev/null +++ b/tests/src/tst_cmc_hashbidimap.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_hashbidimap.h" + + + 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_fval * f_val) { return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey * f_key, struct hashbidimap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); size_t real_capacity = hbm_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); if (!_map_) return ((void *)0); _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_->buffer); alloc->free(_map_); return ((void *)0); } _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->flag = CMC_FLAG_OK; _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->it_start = hbm_impl_it_start; _map_->it_end = hbm_impl_it_end; return _map_; } void hbm_clear(struct hashbidimap * _map_) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashbidimap_entry *entry = _map_->buffer[i][0]; if (entry && entry != ((void *)1)) { if (_map_->f_key->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] = ((void *)0); _map_->buffer[i][1] = ((void *)0); } _map_->count = 0; _map_->flag = CMC_FLAG_OK; } void hbm_free(struct hashbidimap * _map_) { hbm_clear(_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) { ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hbm_insert(struct hashbidimap * _map_, size_t key, size_t value) { if (hbm_full(_map_)) { 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)) { _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); if (!key_entry || !val_entry) { if (key_entry) *key_entry = ((void *)1); if (val_entry) *val_entry = ((void *)1); _map_->alloc->free(entry); _map_->flag = CMC_FLAG_ERROR; return 0; } _map_->count++; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->create) (_map_)->callbacks->create();; return 1; } _Bool hbm_update_key(struct hashbidimap * _map_, size_t val, size_t new_key) { if (hbm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry * *key_entry, **val_entry; val_entry = hbm_impl_get_entry_by_val(_map_, val); if (!val_entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) goto success; if (hbm_impl_get_entry_by_key(_map_, new_key) != ((void *)0)) { _map_->flag = CMC_FLAG_DUPLICATE; return 0; } key_entry = (*val_entry)->ref[0]; if (!key_entry || *key_entry != *val_entry) { _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry *to_add = *key_entry; size_t tmp_key = to_add->key; to_add->key = new_key; *key_entry = ((void *)1); if (!hbm_impl_add_entry_to_key(_map_, to_add)) { to_add->key = tmp_key; *key_entry = to_add; _map_->flag = CMC_FLAG_ERROR; return 0; } success: _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->update) (_map_)->callbacks->update();; return 1; } _Bool hbm_update_val(struct hashbidimap * _map_, size_t key, size_t new_val) { if (hbm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry * *key_entry, **val_entry; key_entry = hbm_impl_get_entry_by_key(_map_, key); if (!key_entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) goto success; if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) { _map_->flag = CMC_FLAG_DUPLICATE; return 0; } val_entry = (*key_entry)->ref[1]; if (!val_entry || *val_entry != *key_entry) { _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry *to_add = *val_entry; size_t tmp_val = to_add->value; to_add->value = new_val; *val_entry = ((void *)1); if (!hbm_impl_add_entry_to_val(_map_, to_add)) { to_add->value = tmp_val; *val_entry = to_add; _map_->flag = CMC_FLAG_ERROR; return 0; } success: _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->update) (_map_)->callbacks->update();; return 1; } _Bool hbm_remove_by_key(struct hashbidimap * _map_, size_t key, size_t * out_key, size_t * out_val) { if (hbm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry * *key_entry, **val_entry; key_entry = hbm_impl_get_entry_by_key(_map_, key); if (!key_entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } val_entry = (*key_entry)->ref[1]; if (!val_entry || *val_entry != *key_entry) { _map_->flag = CMC_FLAG_ERROR; return 0; } if (out_key) *out_key = (*key_entry)->key; if (out_val) *out_val = (*key_entry)->value; _map_->alloc->free(*key_entry); *key_entry = ((void *)1); *val_entry = ((void *)1); _map_->count--; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->delete) (_map_)->callbacks->delete();; return 1; } _Bool hbm_remove_by_val(struct hashbidimap * _map_, size_t val, size_t * out_key, size_t * out_val) { if (hbm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry * *key_entry, **val_entry; val_entry = hbm_impl_get_entry_by_val(_map_, val); if (!val_entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } key_entry = (*val_entry)->ref[0]; if (!key_entry || *key_entry != *val_entry) { _map_->flag = CMC_FLAG_ERROR; return 0; } if (out_key) *out_key = (*val_entry)->key; if (out_val) *out_val = (*val_entry)->value; _map_->alloc->free(*val_entry); *key_entry = ((void *)1); *val_entry = ((void *)1); _map_->count--; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->delete) (_map_)->callbacks->delete();; return 1; } size_t hbm_get_key(struct hashbidimap * _map_, size_t val) { struct hashbidimap_entry **entry = hbm_impl_get_entry_by_val(_map_, val); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return (*entry)->key; } size_t hbm_get_val(struct hashbidimap * _map_, size_t key) { struct hashbidimap_entry **entry = hbm_impl_get_entry_by_key(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return (*entry)->value; } _Bool hbm_contains_key(struct hashbidimap * _map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool hbm_contains_val(struct hashbidimap * _map_, size_t val) { _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool hbm_empty(struct hashbidimap * _map_) { return _map_->count == 0; } _Bool hbm_full(struct hashbidimap * _map_) { return (double)_map_->capacity * _map_->load <= (double)_map_->count; } size_t hbm_count(struct hashbidimap * _map_) { return _map_->count; } size_t hbm_capacity(struct hashbidimap * _map_) { return _map_->capacity; } double hbm_load(struct hashbidimap * _map_) { return _map_->load; } int hbm_flag(struct hashbidimap * _map_) { return _map_->flag; } _Bool hbm_resize(struct hashbidimap * _map_, size_t capacity) { _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = CMC_FLAG_ERROR; return 0; } size_t new_cap = hbm_impl_calculate_size(capacity); if (new_cap < _map_->count / _map_->load) { _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashbidimap *_new_map_ = hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _map_->capacity; i++) { 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); if (!e1 || !e2) { _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); _map_->flag = CMC_FLAG_ERROR; return 0; } _new_map_->count++; } } if (_map_->count != _new_map_->count) { _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry * (*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 1; } struct hashbidimap *hbm_copy_of(struct hashbidimap * _map_) { struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _map_->callbacks; for (size_t i = 0; i < _map_->capacity; i++) { struct hashbidimap_entry *scan = _map_->buffer[i][0]; if (scan && scan != ((void *)1)) { size_t tmp_key; size_t 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; 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++; } } _map_->flag = CMC_FLAG_OK; return result; } _Bool hbm_equals(struct hashbidimap * _map1_, struct hashbidimap * _map2_) { _map1_->flag = CMC_FLAG_OK; _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashbidimap *_mapA_; struct hashbidimap *_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 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); if (!entry_B) return 0; if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) return 0; } } return 1; } struct hashbidimap_iter * hbm_iter_new(struct hashbidimap * target) { struct hashbidimap_iter *iter = target->alloc->malloc(sizeof(struct hashbidimap_iter)); if (!iter) return ((void *)0); hbm_iter_init(iter, target); return iter; } void hbm_iter_free(struct hashbidimap_iter * iter) { iter->target->alloc->free(iter); } void hbm_iter_init(struct hashbidimap_iter * iter, struct hashbidimap * target) { memset(iter, 0, sizeof(struct hashbidimap_iter)); iter->target = target; iter->start = 1; iter->end = hbm_empty(target); if (!hbm_empty(target)) { for (size_t i = 0; i < target->capacity; i++) { struct hashbidimap_entry *entry = target->buffer[i][0]; if (entry && entry != ((void *)1)) { iter->first = i; break; } } iter->cursor = iter->first; for (size_t i = target->capacity; i > 0; i--) { struct hashbidimap_entry *entry = target->buffer[i - 1][0]; if (entry && entry != ((void *)1)) { iter->last = i - 1; break; } } } } _Bool hbm_iter_start(struct hashbidimap_iter * iter) { return hbm_empty(iter->target) || iter->start; } _Bool hbm_iter_end(struct hashbidimap_iter * iter) { return hbm_empty(iter->target) || iter->end; } void hbm_iter_to_start(struct hashbidimap_iter * iter) { if (!hbm_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = 0; } } void hbm_iter_to_end(struct hashbidimap_iter * iter) { if (!hbm_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = 0; iter->end = 1; } } _Bool hbm_iter_next(struct hashbidimap_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = hbm_empty(iter->target); struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; iter->index++; while (1) { iter->cursor++; scan = iter->target->buffer[iter->cursor][0]; if (scan != ((void *)0) && scan != ((void *)1)) break; } return 1; } _Bool hbm_iter_prev(struct hashbidimap_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = hbm_empty(iter->target); struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; iter->index--; while (1) { iter->cursor--; scan = iter->target->buffer[iter->cursor][0]; if (scan != ((void *)0) && scan != ((void *)1)) break; } return 1; } _Bool hbm_iter_advance(struct hashbidimap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hbm_iter_next(iter); return 1; } _Bool hbm_iter_rewind(struct hashbidimap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hbm_iter_prev(iter); return 1; } _Bool hbm_iter_go_to(struct hashbidimap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hbm_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hbm_iter_advance(iter, index - iter->index); return 1; } size_t hbm_iter_key(struct hashbidimap_iter * iter) { if (hbm_empty(iter->target)) { iter->target->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } return iter->target->buffer[iter->cursor][0]->key; } size_t hbm_iter_value(struct hashbidimap_iter * iter) { if (hbm_empty(iter->target)) { iter->target->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } return iter->target->buffer[iter->cursor][0]->value; } 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) { struct hashbidimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashbidimap_entry)); if (!entry) return ((void *)0); entry->key = key; entry->value = value; entry->dist[0] = 0; entry->dist[1] = 0; entry->ref[0] = ((void *)0); entry->ref[1] = ((void *)0); return entry; } 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; struct hashbidimap_entry *target = _map_->buffer[pos][0]; while (target != ((void *)0)) { if (target != ((void *)1) && _map_->f_key->cmp(target->key, key) == 0) return &(_map_->buffer[pos % _map_->capacity][0]); pos++; target = _map_->buffer[pos % _map_->capacity][0]; } return ((void *)0); } 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; struct hashbidimap_entry *target = _map_->buffer[pos][1]; while (target != ((void *)0)) { if (target != ((void *)1) && _map_->f_val->cmp(target->value, val) == 0) return &(_map_->buffer[pos % _map_->capacity][1]); pos++; target = _map_->buffer[pos % _map_->capacity][1]; } return ((void *)0); } 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]); if (*scan == ((void *)0)) { *scan = entry; entry->ref[0] = scan; return scan; } else { while (1) { pos++; scan = &(_map_->buffer[pos % _map_->capacity][0]); if (*scan == ((void *)0) || *scan == ((void *)1)) { 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 hashbidimap_entry *_tmp_ = *scan; *scan = entry; entry = _tmp_; } } } return ((void *)0); } 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]); if (*scan == ((void *)0)) { *scan = entry; entry->ref[1] = scan; return scan; } else { while (1) { pos++; scan = &(_map_->buffer[pos % _map_->capacity][1]); if (*scan == ((void *)0) || *scan == ((void *)1)) { 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 hashbidimap_entry *_tmp_ = *scan; *scan = entry; entry = _tmp_; } } } return ((void *)0); } static size_t hbm_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 hashbidimap_iter hbm_impl_it_start(struct hashbidimap * _map_) { struct hashbidimap_iter iter; hbm_iter_init(&iter, _map_); return iter; } static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap * _map_) { struct hashbidimap_iter iter; hbm_iter_init(&iter, _map_); hbm_iter_to_end(&iter); return iter; } _Bool hbm_to_string(struct hashbidimap * _map_, FILE * fptr) { struct hashbidimap *m_ = _map_; return 0 <= fprintf(fptr, "struct %s<%s, %s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_key:%p, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } _Bool hbm_print(struct hashbidimap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep) { fprintf(fptr, "%s", start); size_t last = 0; for (size_t i = _map_->capacity; i > 0; i--) { struct hashbidimap_entry *entry = _map_->buffer[i - 1][0]; if (entry && entry != ((void *)1)) { last = i - 1; break; } } for (size_t i = 0; i < _map_->capacity; i++) { struct hashbidimap_entry *entry = _map_->buffer[i][0]; if (entry && entry != ((void *)1)) { if (!_map_->f_key->str(fptr, entry->key)) return 0; fprintf(fptr, "%s", key_val_sep); if (!_map_->f_val->str(fptr, entry->value)) return 0; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_hashmap.c b/tests/src/tst_cmc_hashmap.c new file mode 100644 index 0000000..19773cf --- /dev/null +++ b/tests/src/tst_cmc_hashmap.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_hashmap.h" + + + 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) { 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) { ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); size_t real_capacity = hm_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; struct hashmap *_map_ = alloc->malloc(sizeof(struct hashmap)); if (!_map_) return ((void *)0); _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); if (!_map_->buffer) { alloc->free(_map_); return ((void *)0); } _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; (_map_)->callbacks = callbacks; return _map_; } void hm_clear(struct hashmap * _map_) { if (_map_->f_key->free || _map_->f_val->free) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashmap_entry *entry = &(_map_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (_map_->f_key->free) _map_->f_key->free(entry->key); if (_map_->f_val->free) _map_->f_val->free(entry->value); } } } memset(_map_->buffer, 0, sizeof(struct hashmap_entry) * _map_->capacity); _map_->count = 0; _map_->flag = CMC_FLAG_OK; } void hm_free(struct hashmap * _map_) { if (_map_->f_key->free || _map_->f_val->free) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashmap_entry *entry = &(_map_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (_map_->f_key->free) _map_->f_key->free(entry->key); if (_map_->f_val->free) _map_->f_val->free(entry->value); } } } _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } void hm_customize(struct hashmap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hm_insert(struct hashmap * _map_, size_t key, size_t value) { if (hm_full(_map_)) { if (!hm_resize(_map_, _map_->capacity + 1)) return 0; } if (hm_impl_get_entry(_map_, key) != ((void *)0)) { _map_->flag = CMC_FLAG_DUPLICATE; return 0; } size_t hash = _map_->f_key->hash(key); size_t original_pos = hash % _map_->capacity; size_t pos = original_pos; struct hashmap_entry *target = &(_map_->buffer[pos]); if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->key = key; target->value = value; target->dist = 0; target->state = CMC_ES_FILLED; } else { while (1) { 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) { size_t tmp_k = target->key; size_t 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 1; } _Bool hm_update(struct hashmap * _map_, size_t key, size_t new_value, size_t * old_value) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } 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 1; } _Bool hm_remove(struct hashmap * _map_, size_t key, size_t * out_value) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_entry *result = hm_impl_get_entry(_map_, key); if (result == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_value) *out_value = result->value; result->key = (size_t){ 0 }; result->value = (size_t){ 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 1; } _Bool hm_max(struct hashmap * _map_, size_t * key, size_t * value) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { if (first) { max_key = _map_->buffer[i].key; max_val = _map_->buffer[i].value; first = 0; } else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) { max_key = _map_->buffer[i].key; max_val = _map_->buffer[i].value; } } } if (key) *key = max_key; if (value) *value = max_val; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return 1; } _Bool hm_min(struct hashmap * _map_, size_t * key, size_t * value) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t min_key = (size_t){ 0 }; size_t min_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { if (first) { min_key = _map_->buffer[i].key; min_val = _map_->buffer[i].value; first = 0; } else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) { min_key = _map_->buffer[i].key; min_val = _map_->buffer[i].value; } } } if (key) *key = min_key; if (value) *value = min_val; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return 1; } size_t hm_get(struct hashmap * _map_, size_t key) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return entry->value; } size_t *hm_get_ref(struct hashmap * _map_, size_t key) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return ((void *)0); } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return &(entry->value); } _Bool hm_contains(struct hashmap * _map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hm_impl_get_entry(_map_, key) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool hm_empty(struct hashmap * _map_) { return _map_->count == 0; } _Bool hm_full(struct hashmap * _map_) { return (double)_map_->capacity * _map_->load <= (double)_map_->count; } size_t hm_count(struct hashmap * _map_) { return _map_->count; } size_t hm_capacity(struct hashmap * _map_) { return _map_->capacity; } double hm_load(struct hashmap * _map_) { return _map_->load; } int hm_flag(struct hashmap * _map_) { return _map_->flag; } _Bool hm_resize(struct hashmap * _map_, size_t capacity) { _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hm_impl_calculate_size(capacity); if (theoretical_size < _map_->count / _map_->load) { _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashmap *_new_map_ = hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { size_t key = _map_->buffer[i].key; size_t value = _map_->buffer[i].value; hm_insert(_new_map_, key, value); } } if (_map_->count != _new_map_->count) { hm_free(_new_map_); _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashmap_entry *tmp_b = _map_->buffer; _map_->buffer = _new_map_->buffer; _new_map_->buffer = tmp_b; size_t tmp_c = _map_->capacity; _map_->capacity = _new_map_->capacity; _new_map_->capacity = tmp_c; _new_map_->f_key = &(struct hashmap_fkey){ ((void *)0) }; _new_map_->f_val = &(struct hashmap_fval){ ((void *)0) }; hm_free(_new_map_); success: if ((_map_)->callbacks && (_map_)->callbacks->resize) (_map_)->callbacks->resize();; return 1; } struct hashmap *hm_copy_of(struct hashmap * _map_) { struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _map_->callbacks; if (_map_->f_key->cpy || _map_->f_val->cpy) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashmap_entry *scan = &(_map_->buffer[i]); if (scan->state != CMC_ES_EMPTY) { struct hashmap_entry *target = &(result->buffer[i]); if (scan->state == CMC_ES_DELETED) target->state = CMC_ES_DELETED; else { target->state = scan->state; target->dist = scan->dist; if (_map_->f_key->cpy) target->key = _map_->f_key->cpy(scan->key); else target->key = scan->key; if (_map_->f_val->cpy) target->value = _map_->f_val->cpy(scan->value); else target->value = scan->value; } } } } else memcpy(result->buffer, _map_->buffer, sizeof(struct hashmap_entry) * _map_->capacity); result->count = _map_->count; _map_->flag = CMC_FLAG_OK; return result; } _Bool hm_equals(struct hashmap * _map1_, struct hashmap * _map2_) { _map1_->flag = CMC_FLAG_OK; _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashmap *_map_a_; struct hashmap *_map_b_; _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; for (size_t i = 0; i < _map_a_->capacity; i++) { if (_map_a_->buffer[i].state == CMC_ES_FILLED) { struct hashmap_entry *entry_a = &(_map_a_->buffer[i]); struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key); if (!entry_b) return 0; if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) return 0; } } return 1; } static struct hashmap_entry * hm_impl_get_entry(struct hashmap * _map_, size_t key) { size_t hash = _map_->f_key->hash(key); size_t pos = hash % _map_->capacity; struct hashmap_entry *target = &(_map_->buffer[pos]); while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) { if (_map_->f_key->cmp(target->key, key) == 0) return target; pos++; target = &(_map_->buffer[pos % _map_->capacity]); } return ((void *)0); } static size_t hm_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; while (cmc_hashtable_primes[i] < required) i++; return cmc_hashtable_primes[i]; } struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val) { return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; struct hashmap _map_ = { 0 }; if (capacity == 0 || load <= 0 || load >= 1) return _map_; if (capacity >= 0xffffffffffffffffULL * load) return _map_; if (!f_key || !f_val) return _map_; size_t real_capacity = hm_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); if (!_map_.buffer) return _map_; _map_.count = 0; _map_.capacity = real_capacity; _map_.load = load; _map_.flag = CMC_FLAG_OK; _map_.f_key = f_key; _map_.f_val = f_val; _map_.alloc = alloc; (&_map_)->callbacks = callbacks; return _map_; } void hm_release(struct hashmap _map_) { if (_map_.f_key->free || _map_.f_val->free) { for (size_t i = 0; i < _map_.capacity; i++) { struct hashmap_entry *entry = &(_map_.buffer[i]); if (entry->state == CMC_ES_FILLED) { if (_map_.f_key->free) _map_.f_key->free(entry->key); if (_map_.f_val->free) _map_.f_val->free(entry->value); } } } _map_.alloc->free(_map_.buffer); } struct hashmap_iter hm_iter_start(struct hashmap * target) { struct hashmap_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = 1; iter.end = hm_empty(target); if (!hm_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 hashmap_iter hm_iter_end(struct hashmap * target) { struct hashmap_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = hm_empty(target); iter.end = 1; if (!hm_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 hm_iter_at_start(struct hashmap_iter * iter) { return hm_empty(iter->target) || iter->start; } _Bool hm_iter_at_end(struct hashmap_iter * iter) { return hm_empty(iter->target) || iter->end; } _Bool hm_iter_to_start(struct hashmap_iter * iter) { if (!hm_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = hm_empty(iter->target); return 1; } return 0; } _Bool hm_iter_to_end(struct hashmap_iter * iter) { if (!hm_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = hm_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool hm_iter_next(struct hashmap_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = hm_empty(iter->target); struct hashmap_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index++; while (1) { iter->cursor++; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hm_iter_prev(struct hashmap_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = hm_empty(iter->target); struct hashmap_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index--; while (1) { iter->cursor--; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hm_iter_advance(struct hashmap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hm_iter_next(iter); return 1; } _Bool hm_iter_rewind(struct hashmap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hm_iter_prev(iter); return 1; } _Bool hm_iter_go_to(struct hashmap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hm_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hm_iter_advance(iter, index - iter->index); return 1; } size_t hm_iter_key(struct hashmap_iter * iter) { if (hm_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor].key; } size_t hm_iter_value(struct hashmap_iter * iter) { if (hm_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor].value; } size_t *hm_iter_rvalue(struct hashmap_iter * iter) { if (hm_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor].value); } size_t hm_iter_index(struct hashmap_iter * iter) { return iter->index; } _Bool hm_to_string(struct hashmap * _map_, FILE * fptr) { struct hashmap *m_ = _map_; return 0 <= fprintf(fptr, "struct %s<%s, %s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_key:%p, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } _Bool hm_print(struct hashmap * _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 hashmap_entry *entry = &(_map_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (!_map_->f_key->str(fptr, entry->key)) return 0; fprintf(fptr, "%s", key_val_sep); if (!_map_->f_val->str(fptr, entry->value)) return 0; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_hashmultimap.c b/tests/src/tst_cmc_hashmultimap.c new file mode 100644 index 0000000..fa8d7c1 --- /dev/null +++ b/tests/src/tst_cmc_hashmultimap.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_hashmultimap.h" + + + 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_fval * f_val) { return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey * f_key, struct hashmultimap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || load <= 0) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; size_t real_capacity = hmm_impl_calculate_size(capacity / load); struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); if (!_map_) return ((void *)0); _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_); return ((void *)0); } _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; (_map_)->callbacks = callbacks; return _map_; } void hmm_clear(struct hashmultimap * _map_) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { struct hashmultimap_entry *next = scan->next; if (_map_->f_key->free) _map_->f_key->free(scan->key); if (_map_->f_val->free) _map_->f_val->free(scan->value); _map_->alloc->free(scan); scan = next; } } memset(_map_->buffer, 0, sizeof(struct hashmultimap_entry *[2]) * _map_->capacity); _map_->count = 0; _map_->flag = CMC_FLAG_OK; } void hmm_free(struct hashmultimap * _map_) { size_t index = 0; while (index < _map_->capacity) { struct hashmultimap_entry *scan = _map_->buffer[index][0]; if (scan) { if (scan->next == ((void *)0) && scan->prev == ((void *)0)) { 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) { struct hashmultimap_entry *tmp = scan; scan = scan->next; if (_map_->f_key->free) _map_->f_key->free(tmp->key); if (_map_->f_val->free) _map_->f_val->free(tmp->value); _map_->alloc->free(tmp); } } } index++; } _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } void hmm_customize(struct hashmultimap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hmm_insert(struct hashmultimap * _map_, size_t key, size_t value) { if (hmm_full(_map_)) { if (!hmm_resize(_map_, _map_->capacity + 1)) return 0; } size_t hash = _map_->f_key->hash(key); size_t pos = hash % _map_->capacity; struct hashmultimap_entry *entry = hmm_impl_new_entry(_map_, key, value); if (_map_->buffer[pos][0] == ((void *)0)) { _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 1; } _Bool hmm_update(struct hashmultimap * _map_, size_t key, size_t new_value, size_t * old_value) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } 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 1; } size_t hmm_update_all(struct hashmultimap * _map_, size_t key, size_t new_value, size_t * *old_values) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; if (entry == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (old_values) { size_t total = hmm_impl_key_count(_map_, key); if (total == 0) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } *old_values = _map_->alloc->malloc(sizeof(size_t) * total); if (!(*old_values)) { _map_->flag = CMC_FLAG_ALLOC; return 0; } } size_t index = 0; while (entry) { 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 hmm_remove(struct hashmultimap * _map_, size_t key, size_t * out_value) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; 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]); if (*head == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } struct hashmultimap_entry *entry = *head; if (entry->next == ((void *)0) && entry->prev == ((void *)0)) { if (_map_->f_key->cmp(entry->key, key) == 0) { *head = ((void *)0); *tail = ((void *)0); if (out_value) *out_value = entry->value; } else { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } } else { _Bool found = 0; while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) { if (*head == entry) *head = entry->next; if (*tail == entry) *tail = entry->prev; if (entry->prev) entry->prev->next = entry->next; if (entry->next) entry->next->prev = entry->prev; if (out_value) *out_value = entry->value; found = 1; break; } else entry = entry->next; } if (!found) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } } _map_->alloc->free(entry); _map_->count--; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->delete) (_map_)->callbacks->delete();; return 1; } size_t hmm_remove_all(struct hashmultimap * _map_, size_t key, size_t * *out_values) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; 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]); if (*head == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_values) { size_t total = hmm_impl_key_count(_map_, key); if (total == 0) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } *out_values = _map_->alloc->malloc(sizeof(size_t) * total); if (!(*out_values)) { _map_->flag = CMC_FLAG_ALLOC; return 0; } } size_t index = 0; struct hashmultimap_entry *entry = *head; if (entry->next == ((void *)0)) { *head = ((void *)0); *tail = ((void *)0); if (out_values) (*out_values)[index] = entry->value; index++; _map_->alloc->free(entry); } else { while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) { if (*head == entry) *head = entry->next; if (*tail == entry) *tail = entry->prev; struct hashmultimap_entry *next = entry->next; if (entry->prev) entry->prev->next = entry->next; if (entry->next) 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 hmm_max(struct hashmultimap * _map_, size_t * key, size_t * value) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { if (first) { max_key = scan->key; max_val = scan->value; first = 0; } else if (_map_->f_key->cmp(scan->key, max_key) > 0) { max_key = scan->key; max_val = scan->value; } scan = scan->next; } } 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 1; } _Bool hmm_min(struct hashmultimap * _map_, size_t * key, size_t * value) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t min_key = (size_t){ 0 }; size_t min_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { if (first) { min_key = scan->key; min_val = scan->value; first = 0; } else if (_map_->f_key->cmp(scan->key, min_key) < 0) { min_key = scan->key; min_val = scan->value; } scan = scan->next; } } 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 1; } size_t hmm_get(struct hashmultimap * _map_, size_t key) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return entry->value; } size_t *hmm_get_ref(struct hashmultimap * _map_, size_t key) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return ((void *)0); } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return &(entry->value); } _Bool hmm_contains(struct hashmultimap * _map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool hmm_empty(struct hashmultimap * _map_) { return _map_->count == 0; } _Bool hmm_full(struct hashmultimap * _map_) { return (double)_map_->capacity * _map_->load <= (double)_map_->count; } size_t hmm_count(struct hashmultimap * _map_) { return _map_->count; } size_t hmm_key_count(struct hashmultimap * _map_, size_t key) { return hmm_impl_key_count(_map_, key); } size_t hmm_capacity(struct hashmultimap * _map_) { return _map_->capacity; } double hmm_load(struct hashmultimap * _map_) { return _map_->load; } int hmm_flag(struct hashmultimap * _map_) { return _map_->flag; } _Bool hmm_resize(struct hashmultimap * _map_, size_t capacity) { _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hmm_impl_calculate_size(capacity); if (theoretical_size < _map_->count / _map_->load) { _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashmultimap *_new_map_ = hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { hmm_insert(_new_map_, scan->key, scan->value); scan = scan->next; } } if (_map_->count != _new_map_->count) { hmm_free(_new_map_); _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashmultimap_entry * (*tmp_b)[2] = _map_->buffer; _map_->buffer = _new_map_->buffer; _new_map_->buffer = tmp_b; size_t tmp_c = _map_->capacity; _map_->capacity = _new_map_->capacity; _new_map_->capacity = tmp_c; _new_map_->f_key = &(struct hashmultimap_fkey){ ((void *)0) }; _new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) }; hmm_free(_new_map_); success: if ((_map_)->callbacks && (_map_)->callbacks->resize) (_map_)->callbacks->resize();; return 1; } 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)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { size_t key; size_t value; if (_map_->f_key->cpy) key = _map_->f_key->cpy(scan->key); else key = scan->key; if (_map_->f_val->cpy) value = _map_->f_val->cpy(scan->value); else value = scan->value; hmm_insert(result, key, value); scan = scan->next; } } (result)->callbacks = _map_->callbacks; _map_->flag = CMC_FLAG_OK; return result; } _Bool hmm_equals(struct hashmultimap * _map1_, struct hashmultimap * _map2_) { _map1_->flag = CMC_FLAG_OK; _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashmultimap *_map_a_; struct hashmultimap *_map_b_; _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; for (size_t i = 0; i < _map_a_->capacity; i++) { struct hashmultimap_entry *scan = _map_a_->buffer[i][0]; while (scan) { if (hmm_impl_key_count(_map_a_, scan->key) != hmm_impl_key_count(_map_b_, scan->key)) return 0; scan = scan->next; } } return 1; } struct hashmultimap_entry * hmm_impl_new_entry(struct hashmultimap * _map_, size_t key, size_t value) { struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); if (!entry) return ((void *)0); entry->key = key; entry->value = value; entry->next = ((void *)0); entry->prev = ((void *)0); return entry; } struct hashmultimap_entry * hmm_impl_get_entry(struct hashmultimap * _map_, size_t key) { size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) return entry; entry = entry->next; } return ((void *)0); } size_t hmm_impl_key_count(struct hashmultimap * _map_, size_t key) { size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; size_t total_count = 0; if (!entry) return total_count; while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) total_count++; entry = entry->next; } return total_count; } size_t hmm_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; while (cmc_hashtable_primes[i] < required) i++; return cmc_hashtable_primes[i]; } struct hashmultimap_iter hmm_iter_start(struct hashmultimap * target) { struct hashmultimap_iter iter; iter.target = target; iter.curr_entry = ((void *)0); iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = 1; iter.end = hmm_empty(target); if (!hmm_empty(target)) { for (size_t i = 0; i < target->capacity; i++) { struct hashmultimap_entry *entry = target->buffer[i][0]; if (entry && entry != ((void *)1)) { 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 hashmultimap_entry *entry = target->buffer[i - 1][1]; if (entry && entry != ((void *)1)) { iter.last = i - 1; break; } } } return iter; } struct hashmultimap_iter hmm_iter_end(struct hashmultimap * target) { struct hashmultimap_iter iter; iter.target = target; iter.curr_entry = ((void *)0); iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = hmm_empty(target); iter.end = 1; if (!hmm_empty(target)) { for (size_t i = 0; i < target->capacity; i++) { struct hashmultimap_entry *entry = target->buffer[i][0]; if (entry && entry != ((void *)1)) { iter.first = i; break; } } for (size_t i = target->capacity; i > 0; i--) { struct hashmultimap_entry *entry = target->buffer[i - 1][1]; if (entry && entry != ((void *)1)) { iter.curr_entry = target->buffer[i - 1][1]; iter.last = i - 1; break; } } iter.cursor = iter.last; iter.index = target->count - 1; } return iter; } _Bool hmm_iter_at_start(struct hashmultimap_iter * iter) { return hmm_empty(iter->target) || iter->start; } _Bool hmm_iter_at_end(struct hashmultimap_iter * iter) { return hmm_empty(iter->target) || iter->end; } _Bool hmm_iter_to_start(struct hashmultimap_iter * iter) { if (!hmm_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = hmm_empty(iter->target); iter->curr_entry = iter->target->buffer[iter->first][0]; return 1; } return 0; } _Bool hmm_iter_to_end(struct hashmultimap_iter * iter) { if (!hmm_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = hmm_empty(iter->target); iter->end = 1; iter->curr_entry = iter->target->buffer[iter->last][1]; return 1; } return 0; } _Bool hmm_iter_next(struct hashmultimap_iter * iter) { if (iter->end) return 0; if (iter->curr_entry->next != ((void *)0)) { iter->curr_entry = iter->curr_entry->next; iter->index++; } else { if (iter->cursor == iter->last) { iter->end = 1; return 0; } iter->cursor++; while (iter->target->buffer[iter->cursor][0] == ((void *)0)) iter->cursor++; iter->curr_entry = iter->target->buffer[iter->cursor][0]; iter->index++; } iter->start = hmm_empty(iter->target); return 1; } _Bool hmm_iter_prev(struct hashmultimap_iter * iter) { if (iter->start) return 0; if (iter->curr_entry->prev != ((void *)0)) { iter->curr_entry = iter->curr_entry->prev; iter->index--; } else { if (iter->cursor == iter->first) { iter->start = 1; return 0; } iter->cursor--; while (iter->target->buffer[iter->cursor][1] == ((void *)0)) iter->cursor--; iter->curr_entry = iter->target->buffer[iter->cursor][1]; iter->index--; } iter->end = hmm_empty(iter->target); return 1; } _Bool hmm_iter_advance(struct hashmultimap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hmm_iter_next(iter); return 1; } _Bool hmm_iter_rewind(struct hashmultimap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hmm_iter_prev(iter); return 1; } _Bool hmm_iter_go_to(struct hashmultimap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hmm_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hmm_iter_advance(iter, index - iter->index); return 1; } size_t hmm_iter_key(struct hashmultimap_iter * iter) { if (hmm_empty(iter->target)) return (size_t){ 0 }; return iter->curr_entry->key; } size_t hmm_iter_value(struct hashmultimap_iter * iter) { if (hmm_empty(iter->target)) return (size_t){ 0 }; return iter->curr_entry->value; } size_t *hmm_iter_rvalue(struct hashmultimap_iter * iter) { if (hmm_empty(iter->target)) return ((void *)0); return &(iter->curr_entry->value); } size_t hmm_iter_index(struct hashmultimap_iter * iter) { return iter->index; } _Bool hmm_to_string(struct hashmultimap * _map_, FILE * fptr) { struct hashmultimap *m_ = _map_; return 0 <= fprintf(fptr, "struct %s<%s, %s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_key:%p, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } _Bool hmm_print(struct hashmultimap * _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 hashmultimap_entry *entry = _map_->buffer[i - 1][1]; if (entry && entry != ((void *)1)) { last = i - 1; break; } } for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan != ((void *)0)) { if (!_map_->f_key->str(fptr, scan->key)) return 0; fprintf(fptr, "%s", key_val_sep); if (!_map_->f_val->str(fptr, scan->value)) return 0; scan = scan->next; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_hashmultiset.c b/tests/src/tst_cmc_hashmultiset.c new file mode 100644 index 0000000..0a9f492 --- /dev/null +++ b/tests/src/tst_cmc_hashmultiset.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_hashmultiset.h" + + + 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) { return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); } struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_val) return ((void *)0); size_t real_capacity = hms_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); if (!_set_) return ((void *)0); _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); if (!_set_->buffer) { alloc->free(_set_); return ((void *)0); } _set_->count = 0; _set_->cardinality = 0; _set_->capacity = real_capacity; _set_->load = load; _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; (_set_)->callbacks = callbacks; return _set_; } void hms_clear(struct hashmultiset * _set_) { if (_set_->f_val->free) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashmultiset_entry *entry = &(_set_->buffer[i]); if (entry->state == CMC_ES_FILLED) { _set_->f_val->free(entry->value); } } } memset(_set_->buffer, 0, sizeof(struct hashmultiset_entry) * _set_->capacity); _set_->count = 0; _set_->flag = CMC_FLAG_OK; } void hms_free(struct hashmultiset * _set_) { if (_set_->f_val->free) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashmultiset_entry *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 hms_customize(struct hashmultiset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _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); if (!entry) { _set_->flag = CMC_FLAG_ERROR; return 0; } if (!new_node) entry->multiplicity++; _set_->cardinality++; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->create) (_set_)->callbacks->create();; return 1; } _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); if (!entry) { _set_->flag = CMC_FLAG_ERROR; return 0; } 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 1; } _Bool hms_update(struct hashmultiset * _set_, size_t value, size_t multiplicity) { if (multiplicity == 0) { struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); if (!result) goto success; _set_->count--; _set_->cardinality -= result->multiplicity; result->value = (size_t){ 0 }; result->multiplicity = 0; result->dist = 0; result->state = CMC_ES_DELETED; goto success; } _Bool 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; entry->multiplicity = multiplicity; success: _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->update) (_set_)->callbacks->update();; return 1; } _Bool hms_remove(struct hashmultiset * _set_, size_t value) { if (hms_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); if (!result) { _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (result->multiplicity > 1) result->multiplicity--; else { result->value = (size_t){ 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 1; } size_t hms_remove_all(struct hashmultiset * _set_, size_t value) { if (hms_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); if (!result) { _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } size_t removed = result->multiplicity; result->value = (size_t){ 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 hms_max(struct hashmultiset * _set_, size_t * value) { if (hms_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { if (first) { max_val = _set_->buffer[i].value; first = 0; } else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) { max_val = _set_->buffer[i].value; } } } if (value) *value = max_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool hms_min(struct hashmultiset * _set_, size_t * value) { if (hms_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t min_val = (size_t){ 0 }; for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { if (first) { min_val = _set_->buffer[i].value; first = 0; } else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) { min_val = _set_->buffer[i].value; } } } if (value) *value = min_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } size_t hms_multiplicity_of(struct hashmultiset * _set_, size_t value) { struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; if (!entry) return 0; return entry->multiplicity; } _Bool hms_contains(struct hashmultiset * _set_, size_t value) { _set_->flag = CMC_FLAG_OK; _Bool result = hms_impl_get_entry(_set_, value) != ((void *)0); if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return result; } _Bool hms_empty(struct hashmultiset * _set_) { return _set_->count == 0; } _Bool hms_full(struct hashmultiset * _set_) { return (double)_set_->capacity * _set_->load <= (double)_set_->count; } size_t hms_count(struct hashmultiset * _set_) { return _set_->count; } size_t hms_cardinality(struct hashmultiset * _set_) { return _set_->cardinality; } size_t hms_capacity(struct hashmultiset * _set_) { return _set_->capacity; } double hms_load(struct hashmultiset * _set_) { return _set_->load; } int hms_flag(struct hashmultiset * _set_) { return _set_->flag; } _Bool hms_resize(struct hashmultiset * _set_, size_t capacity) { _set_->flag = CMC_FLAG_OK; if (_set_->capacity == capacity) goto success; if (_set_->capacity > capacity / _set_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _set_->load) { _set_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hms_impl_calculate_size(capacity); if (theoretical_size < _set_->count / _set_->load) { _set_->flag = CMC_FLAG_INVALID; return 0; } struct hashmultiset *_new_set_ = hms_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!_new_set_) { _set_->flag = CMC_FLAG_ERROR; return 0; } for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { size_t value = _set_->buffer[i].value; size_t multiplicity = _set_->buffer[i].multiplicity; struct hashmultiset_entry *entry = hms_impl_insert_and_return(_new_set_, value, ((void *)0)); entry->multiplicity = multiplicity; } } if (_set_->count != _new_set_->count) { hms_free(_new_set_); _set_->flag = CMC_FLAG_ERROR; return 0; } struct hashmultiset_entry *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; _new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) }; hms_free(_new_set_); success: if ((_set_)->callbacks && (_set_)->callbacks->resize) (_set_)->callbacks->resize();; return 1; } struct hashmultiset *hms_copy_of(struct hashmultiset * _set_) { struct hashmultiset *result = hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _set_->callbacks; if (_set_->f_val->cpy) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashmultiset_entry *scan = &(_set_->buffer[i]); if (scan->state != CMC_ES_EMPTY) { struct hashmultiset_entry *target = &(result->buffer[i]); if (scan->state == CMC_ES_DELETED) target->state = CMC_ES_DELETED; else { target->state = scan->state; target->dist = scan->dist; target->multiplicity = scan->multiplicity; target->value = _set_->f_val->cpy(scan->value); } } } } else memcpy(result->buffer, _set_->buffer, sizeof(struct hashmultiset_entry) * _set_->capacity); result->count = _set_->count; result->cardinality = _set_->cardinality; _set_->flag = CMC_FLAG_OK; return result; } _Bool hms_equals(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; if (_set1_->cardinality != _set2_->cardinality) return 0; if (_set1_->count == 0) return 1; struct hashmultiset *_set_a_; struct hashmultiset *_set_b_; _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; for (size_t i = 0; i < _set_a_->capacity; i++) { if (_set_a_->buffer[i].state == CMC_ES_FILLED) { struct hashmultiset_entry *entry_a = &(_set_a_->buffer[i]); struct hashmultiset_entry *entry_b = hms_impl_get_entry(_set_b_, entry_a->value); if (!entry_b) return 0; if (entry_a->multiplicity != entry_b->multiplicity) return 0; } } return 1; } static size_t hms_impl_multiplicity_of(struct hashmultiset * _set_, size_t value) { struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); if (!entry) return 0; return entry->multiplicity; } static struct hashmultiset_entry * hms_impl_insert_and_return(struct hashmultiset * _set_, size_t value, _Bool *new_node) { if (new_node) *new_node = 0; struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); if (entry != ((void *)0)) return entry; if (new_node) *new_node = 1; if (hms_full(_set_)) { if (!hms_resize(_set_, _set_->capacity + 1)) return ((void *)0); } size_t hash = _set_->f_val->hash(value); size_t original_pos = hash % _set_->capacity; size_t pos = original_pos; size_t curr_mul = 1; struct hashmultiset_entry *target = &(_set_->buffer[pos]); struct hashmultiset_entry *to_return = ((void *)0); if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->value = value; target->multiplicity = curr_mul; target->dist = pos - original_pos; target->state = CMC_ES_FILLED; to_return = target; } else { while (1) { pos++; target = &(_set_->buffer[pos % _set_->capacity]); if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->value = value; target->multiplicity = curr_mul; target->dist = pos - original_pos; target->state = CMC_ES_FILLED; if (!to_return) to_return = target; break; } else if (target->dist < pos - original_pos) { size_t tmp = target->value; size_t tmp_dist = target->dist; size_t tmp_mul = target->multiplicity; target->value = value; target->dist = pos - original_pos; target->multiplicity = curr_mul; value = tmp; original_pos = pos - tmp_dist; curr_mul = tmp_mul; if (!to_return) to_return = target; } } } _set_->count++; return to_return; } static struct hashmultiset_entry * hms_impl_get_entry(struct hashmultiset * _set_, size_t value) { size_t hash = _set_->f_val->hash(value); size_t pos = hash % _set_->capacity; struct hashmultiset_entry *target = &(_set_->buffer[pos]); while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) { if (_set_->f_val->cmp(target->value, value) == 0) return target; pos++; target = &(_set_->buffer[pos % _set_->capacity]); } return ((void *)0); } static size_t hms_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; while (cmc_hashtable_primes[i] < required) i++; return cmc_hashtable_primes[i]; } struct hashmultiset_iter hms_iter_start(struct hashmultiset * target) { struct hashmultiset_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = 1; iter.end = hms_empty(target); if (!hms_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 hashmultiset_iter hms_iter_end(struct hashmultiset * target) { struct hashmultiset_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = hms_empty(target); iter.end = 1; if (!hms_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 hms_iter_at_start(struct hashmultiset_iter * iter) { return hms_empty(iter->target) || iter->start; } _Bool hms_iter_at_end(struct hashmultiset_iter * iter) { return hms_empty(iter->target) || iter->end; } _Bool hms_iter_to_start(struct hashmultiset_iter * iter) { if (!hms_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = hms_empty(iter->target); return 1; } return 0; } _Bool hms_iter_to_end(struct hashmultiset_iter * iter) { if (!hms_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = hms_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool hms_iter_next(struct hashmultiset_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = hms_empty(iter->target); struct hashmultiset_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index++; while (1) { iter->cursor++; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hms_iter_prev(struct hashmultiset_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = hms_empty(iter->target); struct hashmultiset_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index--; while (1) { iter->cursor--; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hms_iter_advance(struct hashmultiset_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hms_iter_next(iter); return 1; } _Bool hms_iter_rewind(struct hashmultiset_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hms_iter_prev(iter); return 1; } _Bool hms_iter_go_to(struct hashmultiset_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hms_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hms_iter_advance(iter, index - iter->index); return 1; } size_t hms_iter_value(struct hashmultiset_iter * iter) { if (hms_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor].value; } size_t hms_iter_multiplicity(struct hashmultiset_iter * iter) { if (hms_empty(iter->target)) return 0; return iter->target->buffer[iter->cursor].multiplicity; } size_t hms_iter_index(struct hashmultiset_iter * iter) { return iter->index; } 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)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); struct hashmultiset_iter iter2 = hms_iter_start(_set2_); for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { size_t value = hms_iter_value(&iter1); size_t m1 = hms_iter_multiplicity(&iter1); size_t m2 = hms_impl_multiplicity_of(_set2_, value); size_t max_ = m1 > m2 ? m1 : m2; hms_update(_set_r_, value, max_); } for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { size_t value = hms_iter_value(&iter2); size_t m1 = hms_impl_multiplicity_of(_set1_, value); size_t m2 = hms_iter_multiplicity(&iter2); size_t max_ = m1 > m2 ? m1 : m2; hms_update(_set_r_, value, max_); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashmultiset *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)); if (!_set_r_) return ((void *)0); struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; struct hashmultiset_iter iter = hms_iter_start(_set_A_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); size_t m1 = hms_iter_multiplicity(&iter); size_t m2 = hms_impl_multiplicity_of(_set_B_, value); size_t max_ = m1 < m2 ? m1 : m2; hms_update(_set_r_, value, max_); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashmultiset *hms_difference(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { struct hashmultiset *_set_r_ = hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); size_t m1 = hms_iter_multiplicity(&iter); size_t m2 = hms_impl_multiplicity_of(_set2_, value); if (m1 > m2) hms_update(_set_r_, value, m1 - m2); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashmultiset *hms_summation(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { struct hashmultiset *_set_r_ = hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); struct hashmultiset_iter iter2 = hms_iter_start(_set2_); for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { hms_insert_many (_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); } for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { hms_insert_many (_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashmultiset *hms_symmetric_difference(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { struct hashmultiset *_set_r_ = hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); struct hashmultiset_iter iter2 = hms_iter_start(_set2_); for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { size_t value = hms_iter_value(&iter1); size_t m1 = hms_iter_multiplicity(&iter1); size_t m2 = hms_impl_multiplicity_of(_set2_, value); if (m1 != m2) { if (m1 > m2) hms_update(_set_r_, value, m1 - m2); else hms_update(_set_r_, value, m2 - m1); } } for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { size_t value = hms_iter_value(&iter2); size_t m1 = hms_impl_multiplicity_of(_set1_, value); size_t m2 = hms_iter_multiplicity(&iter2); if (m1 != m2) { if (m1 > m2) hms_update(_set_r_, value, m1 - m2); else hms_update(_set_r_, value, m2 - m1); } } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } _Bool hms_is_subset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { if (_set1_->count > _set2_->count) return 0; if (hms_empty(_set1_)) return 1; struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); size_t m1 = hms_iter_multiplicity(&iter); size_t m2 = hms_impl_multiplicity_of(_set2_, value); if (m1 > m2) return 0; } return 1; } _Bool hms_is_superset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { return hms_is_subset(_set2_, _set1_); } _Bool hms_is_proper_subset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { if (_set1_->count >= _set2_->count) return 0; if (hms_empty(_set1_)) { if (!hms_empty(_set2_)) return 1; else return 0; } struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); size_t m1 = hms_iter_multiplicity(&iter); size_t m2 = hms_impl_multiplicity_of(_set2_, value); if (m1 >= m2) return 0; } return 1; } _Bool hms_is_proper_superset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { return hms_is_proper_subset(_set2_, _set1_); } _Bool hms_is_disjointset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { if (hms_empty(_set1_)) return 1; struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); if (hms_impl_get_entry(_set2_, value) != ((void *)0)) return 0; } return 1; } _Bool hms_to_string(struct hashmultiset * _set_, FILE * fptr) { struct hashmultiset *s_ = _set_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "cardinality:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); } _Bool hms_print(struct hashmultiset * _set_, FILE * fptr, const char *start, const char *separator, const char *end, const char *val_mul_sep) { fprintf(fptr, "%s", start); size_t last = 0; for (size_t i = _set_->capacity; i > 0; i--) { if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) { last = i - 1; break; } } for (size_t i = 0; i < _set_->capacity; i++) { struct hashmultiset_entry *entry = &(_set_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (!_set_->f_val->str(fptr, entry->value)) return 0; fprintf(fptr, "%s", val_mul_sep); if (fprintf(fptr, "%" "I64u" "", entry->multiplicity) < 0) return 0; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_hashset.c b/tests/src/tst_cmc_hashset.c new file mode 100644 index 0000000..f82410a --- /dev/null +++ b/tests/src/tst_cmc_hashset.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_hashset.h" + + + static struct hashset_entry * hs_impl_get_entry(struct hashset * _set_, size_t value); static size_t hs_impl_calculate_size(size_t required); struct hashset *hs_new(size_t capacity, double load, struct hashset_fval * f_val) { return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); } struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_val) return ((void *)0); size_t real_capacity = hs_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; struct hashset *_set_ = alloc->malloc(sizeof(struct hashset)); if (!_set_) return ((void *)0); _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry)); if (!_set_->buffer) { alloc->free(_set_); return ((void *)0); } _set_->count = 0; _set_->capacity = real_capacity; _set_->load = load; _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; (_set_)->callbacks = callbacks; return _set_; } void hs_clear(struct hashset * _set_) { if (_set_->f_val->free) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashset_entry *entry = &(_set_->buffer[i]); if (entry->state == CMC_ES_FILLED) { _set_->f_val->free(entry->value); } } } memset(_set_->buffer, 0, sizeof(struct hashset_entry) * _set_->capacity); _set_->count = 0; _set_->flag = CMC_FLAG_OK; } void hs_free(struct hashset * _set_) { if (_set_->f_val->free) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashset_entry *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 hs_customize(struct hashset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool hs_insert(struct hashset * _set_, size_t value) { if (hs_full(_set_)) { if (!hs_resize(_set_, _set_->capacity + 1)) return 0; } if (hs_impl_get_entry(_set_, value) != ((void *)0)) { _set_->flag = CMC_FLAG_DUPLICATE; return 0; } size_t hash = _set_->f_val->hash(value); size_t original_pos = hash % _set_->capacity; size_t pos = original_pos; struct hashset_entry *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 (1) { 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) { size_t 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 1; } _Bool hs_remove(struct hashset * _set_, size_t value) { if (hs_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashset_entry *result = hs_impl_get_entry(_set_, value); if (result == ((void *)0)) { _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } result->value = (size_t){ 0 }; result->dist = 0; result->state = CMC_ES_DELETED; _set_->count--; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->delete) (_set_)->callbacks->delete();; return 1; } _Bool hs_max(struct hashset * _set_, size_t * value) { if (hs_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { if (first) { max_val = _set_->buffer[i].value; first = 0; } else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) { max_val = _set_->buffer[i].value; } } } if (value) *value = max_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool hs_min(struct hashset * _set_, size_t * value) { if (hs_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t min_val = (size_t){ 0 }; for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { if (first) { min_val = _set_->buffer[i].value; first = 0; } else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) { min_val = _set_->buffer[i].value; } } } if (value) *value = min_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool hs_contains(struct hashset * _set_, size_t value) { _set_->flag = CMC_FLAG_OK; _Bool result = hs_impl_get_entry(_set_, value) != ((void *)0); if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return result; } _Bool hs_empty(struct hashset * _set_) { return _set_->count == 0; } _Bool hs_full(struct hashset * _set_) { return (double)_set_->capacity * _set_->load <= (double)_set_->count; } size_t hs_count(struct hashset * _set_) { return _set_->count; } size_t hs_capacity(struct hashset * _set_) { return _set_->capacity; } double hs_load(struct hashset * _set_) { return _set_->load; } int hs_flag(struct hashset * _set_) { return _set_->flag; } _Bool hs_resize(struct hashset * _set_, size_t capacity) { _set_->flag = CMC_FLAG_OK; if (_set_->capacity == capacity) goto success; if (_set_->capacity > capacity / _set_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _set_->load) { _set_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hs_impl_calculate_size(capacity); if (theoretical_size < _set_->count / _set_->load) { _set_->flag = CMC_FLAG_INVALID; return 0; } struct hashset *_new_set_ = hs_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!_new_set_) { _set_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { size_t value = _set_->buffer[i].value; hs_insert(_new_set_, value); } } if (_set_->count != _new_set_->count) { hs_free(_new_set_); _set_->flag = CMC_FLAG_ERROR; return 0; } struct hashset_entry *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; _new_set_->f_val = &(struct hashset_fval){ ((void *)0) }; hs_free(_new_set_); success: if ((_set_)->callbacks && (_set_)->callbacks->resize) (_set_)->callbacks->resize();; return 1; } struct hashset *hs_copy_of(struct hashset * _set_) { struct hashset *result = hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _set_->callbacks; if (_set_->f_val->cpy) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashset_entry *scan = &(_set_->buffer[i]); if (scan->state != CMC_ES_EMPTY) { struct hashset_entry *target = &(result->buffer[i]); if (scan->state == CMC_ES_DELETED) target->state = CMC_ES_DELETED; else { target->state = scan->state; target->dist = scan->dist; target->value = _set_->f_val->cpy(scan->value); } } } } else memcpy(result->buffer, _set_->buffer, sizeof(struct hashset_entry) * _set_->capacity); result->count = _set_->count; _set_->flag = CMC_FLAG_OK; return result; } _Bool hs_equals(struct hashset * _set1_, struct hashset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; struct hashset *_set_a_; struct hashset *_set_b_; _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; for (size_t i = 0; i < _set_a_->capacity; i++) { if (_set_a_->buffer[i].state == CMC_ES_FILLED) { if (!hs_impl_get_entry(_set_b_, _set_a_->buffer[i].value)) return 0; } } return 1; } 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; struct hashset_entry *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 ((void *)0); } static size_t hs_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; while (cmc_hashtable_primes[i] < required) i++; return cmc_hashtable_primes[i]; } struct hashset_iter hs_iter_start(struct hashset * target) { struct hashset_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = 1; iter.end = hs_empty(target); if (!hs_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 hashset_iter hs_iter_end(struct hashset * target) { struct hashset_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = hs_empty(target); iter.end = 1; if (!hs_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 hs_iter_at_start(struct hashset_iter * iter) { return hs_empty(iter->target) || iter->start; } _Bool hs_iter_at_end(struct hashset_iter * iter) { return hs_empty(iter->target) || iter->end; } _Bool hs_iter_to_start(struct hashset_iter * iter) { if (!hs_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = hs_empty(iter->target); return 1; } return 0; } _Bool hs_iter_to_end(struct hashset_iter * iter) { if (!hs_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = hs_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool hs_iter_next(struct hashset_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = hs_empty(iter->target); struct hashset_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index++; while (1) { iter->cursor++; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hs_iter_prev(struct hashset_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = hs_empty(iter->target); struct hashset_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index--; while (1) { iter->cursor--; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hs_iter_advance(struct hashset_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hs_iter_next(iter); return 1; } _Bool hs_iter_rewind(struct hashset_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hs_iter_prev(iter); return 1; } _Bool hs_iter_go_to(struct hashset_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hs_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hs_iter_advance(iter, index - iter->index); return 1; } size_t hs_iter_value(struct hashset_iter * iter) { if (hs_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor].value; } size_t hs_iter_index(struct hashset_iter * iter) { return iter->index; } 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)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter1 = hs_iter_start(_set1_); struct hashset_iter iter2 = hs_iter_start(_set2_); for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) { hs_insert(_set_r_, hs_iter_value(&iter1)); } for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) { hs_insert(_set_r_, hs_iter_value(&iter2)); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } 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)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; struct hashset_iter iter = hs_iter_start(_set_A_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) hs_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashset *hs_difference(struct hashset * _set1_, struct hashset * _set2_) { struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter = hs_iter_start(_set1_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set2_, value) == ((void *)0)) hs_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashset *hs_symmetric_difference(struct hashset * _set1_, struct hashset * _set2_) { struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter1 = hs_iter_start(_set1_); struct hashset_iter iter2 = hs_iter_start(_set2_); for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) { size_t value = hs_iter_value(&iter1); if (hs_impl_get_entry(_set2_, value) == ((void *)0)) hs_insert(_set_r_, value); } for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) { size_t value = hs_iter_value(&iter2); if (hs_impl_get_entry(_set1_, value) == ((void *)0)) hs_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } _Bool hs_is_subset(struct hashset * _set1_, struct hashset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count > _set2_->count) return 0; if (hs_empty(_set1_)) return 1; struct hashset_iter iter = hs_iter_start(_set1_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set2_, value) == ((void *)0)) return 0; } return 1; } _Bool hs_is_superset(struct hashset * _set1_, struct hashset * _set2_) { return hs_is_subset(_set2_, _set1_); } _Bool hs_is_proper_subset(struct hashset * _set1_, struct hashset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count >= _set2_->count) return 0; if (hs_empty(_set1_)) { if (!hs_empty(_set2_)) return 1; else return 0; } struct hashset_iter iter = hs_iter_start(_set1_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set2_, value) == ((void *)0)) return 0; } return 1; } _Bool hs_is_proper_superset(struct hashset * _set1_, struct hashset * _set2_) { return hs_is_proper_subset(_set2_, _set1_); } _Bool hs_is_disjointset(struct hashset * _set1_, struct hashset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (hs_empty(_set1_)) return 1; struct hashset_iter iter = hs_iter_start(_set1_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set2_, value) != ((void *)0)) return 0; } return 1; } _Bool hs_to_string(struct hashset * _set_, FILE * fptr) { struct hashset *s_ = _set_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks: %p }", "hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); } _Bool hs_print(struct hashset * _set_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); size_t last = 0; for (size_t i = _set_->capacity; i > 0; i--) { if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) { last = i - 1; break; } } for (size_t i = 0; i < _set_->capacity; i++) { struct hashset_entry *entry = &(_set_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (!_set_->f_val->str(fptr, entry->value)) return 0; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_heap.c b/tests/src/tst_cmc_heap.c new file mode 100644 index 0000000..583a76e --- /dev/null +++ b/tests/src/tst_cmc_heap.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_heap.h" + + + 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) { return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0)); } struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct heap *_heap_ = alloc->malloc(sizeof(struct heap)); if (!_heap_) return ((void *)0); _heap_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_heap_->buffer) { alloc->free(_heap_); return ((void *)0); } _heap_->capacity = capacity; _heap_->count = 0; _heap_->HO = HO; _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; (_heap_)->callbacks = callbacks; return _heap_; } void h_clear(struct heap * _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(size_t) * _heap_->capacity); _heap_->count = 0; _heap_->flag = CMC_FLAG_OK; } void h_free(struct heap * _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 h_customize(struct heap * _heap_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _heap_->alloc = &cmc_alloc_node_default; else _heap_->alloc = alloc; (_heap_)->callbacks = callbacks; _heap_->flag = CMC_FLAG_OK; } _Bool h_insert(struct heap * _heap_, size_t value) { if (h_full(_heap_)) { if (!h_resize(_heap_, _heap_->count * 2)) return 0; } _heap_->buffer[_heap_->count++] = value; if (_heap_->count > 1) { h_impl_float_up(_heap_, _heap_->count - 1); } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->create) (_heap_)->callbacks->create();; return 1; } _Bool h_remove(struct heap * _heap_) { if (h_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; _heap_->buffer[_heap_->count - 1] = (size_t){ 0 }; _heap_->count--; h_impl_float_down(_heap_, 0); _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->delete) (_heap_)->callbacks->delete();; return 1; } size_t h_peek(struct heap * _heap_) { if (h_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; return _heap_->buffer[0]; } _Bool h_contains(struct heap * _heap_, size_t value) { _heap_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _heap_->count; i++) { if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) { result = 1; break; } } if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; return result; } _Bool h_empty(struct heap * _heap_) { return _heap_->count == 0; } _Bool h_full(struct heap * _heap_) { return _heap_->count >= _heap_->capacity; } size_t h_count(struct heap * _heap_) { return _heap_->count; } size_t h_capacity(struct heap * _heap_) { return _heap_->capacity; } int h_flag(struct heap * _heap_) { return _heap_->flag; } _Bool h_resize(struct heap * _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 0; } size_t *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _heap_->flag = CMC_FLAG_ALLOC; return 0; } _heap_->buffer = new_buffer; _heap_->capacity = capacity; success: if ((_heap_)->callbacks && (_heap_)->callbacks->resize) (_heap_)->callbacks->resize();; return 1; } struct heap *h_copy_of(struct heap * _heap_) { struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0)); if (!result) { _heap_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _heap_->callbacks; if (_heap_->f_val->cpy) { for (size_t i = 0; i < _heap_->count; i++) result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); } else memcpy(result->buffer, _heap_->buffer, sizeof(size_t) * _heap_->count); result->count = _heap_->count; _heap_->flag = CMC_FLAG_OK; return result; } _Bool h_equals(struct heap * _heap1_, struct heap * _heap2_) { _heap1_->flag = CMC_FLAG_OK; _heap2_->flag = CMC_FLAG_OK; if (_heap1_->count != _heap2_->count) return 0; for (size_t i = 0; i < _heap1_->count; i++) { if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) return 0; } return 1; } static void h_impl_float_up(struct heap * _heap_, size_t index) { size_t C = index; size_t child = _heap_->buffer[C]; size_t parent = _heap_->buffer[(index - 1) / 2]; int mod = _heap_->HO; while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) { size_t tmp = _heap_->buffer[C]; _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; _heap_->buffer[(C - 1) / 2] = tmp; C = (C - 1) / 2; if (C == 0) break; child = _heap_->buffer[C]; parent = _heap_->buffer[(C - 1) / 2]; } } static void h_impl_float_down(struct heap * _heap_, size_t index) { int mod = _heap_->HO; while (index < _heap_->count) { size_t L = 2 * index + 1; size_t R = 2 * index + 2; size_t C = index; if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) { C = L; } if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) { C = R; } if (C != index) { size_t tmp = _heap_->buffer[index]; _heap_->buffer[index] = _heap_->buffer[C]; _heap_->buffer[C] = tmp; index = C; } else break; } } struct heap_iter h_iter_start(struct heap * target) { struct heap_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = h_empty(target); return iter; } struct heap_iter h_iter_end(struct heap * target) { struct heap_iter iter; iter.target = target; iter.cursor = 0; iter.start = h_empty(target); iter.end = 1; if (!h_empty(target)) iter.cursor = target->count - 1; return iter; } _Bool h_iter_at_start(struct heap_iter * iter) { return h_empty(iter->target) || iter->start; } _Bool h_iter_at_end(struct heap_iter * iter) { return h_empty(iter->target) || iter->end; } _Bool h_iter_to_start(struct heap_iter * iter) { if (!h_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = h_empty(iter->target); return 1; } return 0; } _Bool h_iter_to_end(struct heap_iter * iter) { if (!h_empty(iter->target)) { iter->cursor = iter->target->count - 1; iter->start = h_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool h_iter_next(struct heap_iter * iter) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = h_empty(iter->target); iter->cursor++; return 1; } _Bool h_iter_prev(struct heap_iter * iter) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } iter->end = h_empty(iter->target); iter->cursor--; return 1; } _Bool h_iter_advance(struct heap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; if (iter->end) return 0; iter->start = h_empty(iter->target); iter->cursor += steps; return 1; } _Bool h_iter_rewind(struct heap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->end = h_empty(iter->target); iter->cursor -= steps; return 1; } _Bool h_iter_go_to(struct heap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return h_iter_rewind(iter, iter->cursor - index); else if (iter->cursor < index) return h_iter_advance(iter, index - iter->cursor); return 1; } size_t h_iter_value(struct heap_iter * iter) { if (h_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t h_iter_index(struct heap_iter * iter) { return iter->cursor; } _Bool h_to_string(struct heap * _heap_, FILE * fptr) { struct heap *h_ = _heap_; const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "type:%s, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks: %p}", "heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, (h_)->callbacks); } _Bool h_print(struct heap * _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 0; if (i + 1 < _heap_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_intervalheap.c b/tests/src/tst_cmc_intervalheap.c new file mode 100644 index 0000000..38d680c --- /dev/null +++ b/tests/src/tst_cmc_intervalheap.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_intervalheap.h" + + + static void ih_impl_float_up_max(struct intervalheap * _heap_); static void ih_impl_float_up_min(struct intervalheap * _heap_); static void ih_impl_float_down_max(struct intervalheap * _heap_); static void ih_impl_float_down_min(struct intervalheap * _heap_); struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval * f_val) { return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || capacity == 0xffffffffffffffffULL) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap)); if (!_heap_) return ((void *)0); capacity = (capacity + capacity % 2) / 2; _heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2])); if (!_heap_->buffer) { alloc->free(_heap_); return ((void *)0); } _heap_->capacity = capacity; _heap_->size = 0; _heap_->count = 0; _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; (_heap_)->callbacks = callbacks; return _heap_; } void ih_clear(struct intervalheap * _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(size_t[2]) * _heap_->capacity); _heap_->size = 0; _heap_->count = 0; _heap_->flag = CMC_FLAG_OK; } void ih_free(struct intervalheap * _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 ih_customize(struct intervalheap * _heap_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _heap_->alloc = &cmc_alloc_node_default; else _heap_->alloc = alloc; (_heap_)->callbacks = callbacks; _heap_->flag = CMC_FLAG_OK; } _Bool ih_insert(struct intervalheap * _heap_, size_t value) { if (ih_full(_heap_)) { if (!ih_resize(_heap_, _heap_->capacity * 4)) return 0; } if (_heap_->count % 2 == 0) { _heap_->buffer[_heap_->size][0] = value; _heap_->buffer[_heap_->size][1] = (size_t){ 0 }; _heap_->size++; } else { size_t(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); if (_heap_->f_val->cmp((*node)[0], value) > 0) { (*node)[1] = (*node)[0]; (*node)[0] = value; } else { (*node)[1] = value; } } _heap_->count++; _heap_->flag = CMC_FLAG_OK; if (_heap_->count > 2) { size_t(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); if (_heap_->f_val->cmp((*parent)[0], value) > 0) ih_impl_float_up_min(_heap_); else if (_heap_->f_val->cmp((*parent)[1], value) < 0) ih_impl_float_up_max(_heap_); } if ((_heap_)->callbacks && (_heap_)->callbacks->create) (_heap_)->callbacks->create();; return 1; } _Bool ih_remove_max(struct intervalheap * _heap_) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) { _heap_->buffer[0][0] = (size_t){ 0 }; _heap_->count--; _heap_->size--; goto success; } size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); if (_heap_->count % 2 == 1) { _heap_->buffer[0][1] = (*last_node)[0]; (*last_node)[0] = (size_t){ 0 }; _heap_->size--; } else { _heap_->buffer[0][1] = (*last_node)[1]; (*last_node)[1] = (size_t){ 0 }; } _heap_->count--; ih_impl_float_down_max(_heap_); success: _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->delete) (_heap_)->callbacks->delete();; return 1; } _Bool ih_remove_min(struct intervalheap * _heap_) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) { _heap_->buffer[0][0] = (size_t){ 0 }; _heap_->count--; _heap_->size--; goto success; } size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); _heap_->buffer[0][0] = (*last_node)[0]; if (_heap_->count % 2 == 1) { (*last_node)[0] = (size_t){ 0 }; _heap_->size--; } else { (*last_node)[0] = (*last_node)[1]; (*last_node)[1] = (size_t){ 0 }; } _heap_->count--; ih_impl_float_down_min(_heap_); success: _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->delete) (_heap_)->callbacks->delete();; return 1; } _Bool ih_update_max(struct intervalheap * _heap_, size_t value) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) { _heap_->buffer[0][0] = value; } else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0) { _heap_->buffer[0][1] = _heap_->buffer[0][0]; _heap_->buffer[0][0] = value; ih_impl_float_down_max(_heap_); } else { _heap_->buffer[0][1] = value; ih_impl_float_down_max(_heap_); } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->update) (_heap_)->callbacks->update();; return 1; } _Bool ih_update_min(struct intervalheap * _heap_, size_t value) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) { _heap_->buffer[0][0] = value; } else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) { _heap_->buffer[0][0] = _heap_->buffer[0][1]; _heap_->buffer[0][1] = value; ih_impl_float_down_min(_heap_); } else { _heap_->buffer[0][0] = value; ih_impl_float_down_min(_heap_); } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->update) (_heap_)->callbacks->update();; return 1; } size_t ih_max(struct intervalheap * _heap_) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; if (_heap_->count == 1) return _heap_->buffer[0][0]; return _heap_->buffer[0][1]; } size_t ih_min(struct intervalheap * _heap_) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; return _heap_->buffer[0][0]; } _Bool ih_contains(struct intervalheap * _heap_, size_t value) { _heap_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _heap_->count; i++) { if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0) { result = 1; break; } } if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; return result; } _Bool ih_empty(struct intervalheap * _heap_) { return _heap_->count == 0; } _Bool ih_full(struct intervalheap * _heap_) { return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; } size_t ih_count(struct intervalheap * _heap_) { return _heap_->count; } size_t ih_capacity(struct intervalheap * _heap_) { return _heap_->capacity; } int ih_flag(struct intervalheap * _heap_) { return _heap_->flag; } _Bool ih_resize(struct intervalheap * _heap_, size_t capacity) { if (_heap_->capacity == capacity) goto success; if (capacity < _heap_->count) { _heap_->flag = CMC_FLAG_INVALID; return 0; } if (capacity == 0xffffffffffffffffULL) { _heap_->flag = CMC_FLAG_ERROR; return 0; } capacity += capacity % 2; size_t(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity); if (!new_buffer) { _heap_->flag = CMC_FLAG_ALLOC; return 0; } if (capacity > _heap_->capacity) { memset(new_buffer + _heap_->capacity, 0, sizeof(size_t[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 1; } struct intervalheap *ih_copy_of(struct intervalheap * _heap_) { 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); if (!result->buffer) { _heap_->alloc->free(result); _heap_->flag = CMC_FLAG_ALLOC; return ((void *)0); } 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(size_t[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 ih_equals(struct intervalheap * _heap1_, struct intervalheap * _heap2_) { _heap1_->flag = CMC_FLAG_OK; _heap2_->flag = CMC_FLAG_OK; if (_heap1_->count != _heap2_->count) return 0; for (size_t i = 0; i < _heap1_->count; i++) { size_t value1 = _heap1_->buffer[i / 2][i % 2]; size_t value2 = _heap2_->buffer[i / 2][i % 2]; if (_heap1_->f_val->cmp(value1, value2) != 0) return 0; } return 1; } static void ih_impl_float_up_max(struct intervalheap * _heap_) { size_t index = _heap_->size - 1; size_t(*curr_node)[2] = &(_heap_->buffer[index]); while (index > 0) { size_t P_index = (index - 1) / 2; size_t(*parent)[2] = &(_heap_->buffer[P_index]); if (index == _heap_->size - 1 && _heap_->count % 2 != 0) { if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0) break; size_t tmp = (*curr_node)[0]; (*curr_node)[0] = (*parent)[1]; (*parent)[1] = tmp; } else { if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0) break; size_t tmp = (*curr_node)[1]; (*curr_node)[1] = (*parent)[1]; (*parent)[1] = tmp; } index = P_index; curr_node = parent; } } static void ih_impl_float_up_min(struct intervalheap * _heap_) { size_t index = _heap_->size - 1; size_t(*curr_node)[2] = &(_heap_->buffer[index]); while (index > 0) { size_t P_index = (index - 1) / 2; size_t(*parent)[2] = &(_heap_->buffer[P_index]); if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) break; size_t tmp = (*curr_node)[0]; (*curr_node)[0] = (*parent)[0]; (*parent)[0] = tmp; index = P_index; curr_node = parent; } } static void ih_impl_float_down_max(struct intervalheap * _heap_) { size_t index = 0; size_t(*curr_node)[2] = &(_heap_->buffer[index]); while (1) { if (2 * index + 1 >= _heap_->size) break; size_t child; size_t L_index = index * 2 + 1; size_t R_index = index * 2 + 2; if (R_index < _heap_->size) { 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; else child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index; } else child = L_index; size_t(*child_node)[2] = &(_heap_->buffer[child]); if (child == _heap_->size - 1 && _heap_->count % 2 != 0) { if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0) break; size_t tmp = (*child_node)[0]; (*child_node)[0] = (*curr_node)[1]; (*curr_node)[1] = tmp; } else { if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0) break; size_t tmp = (*child_node)[1]; (*child_node)[1] = (*curr_node)[1]; (*curr_node)[1] = tmp; if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) { tmp = (*child_node)[0]; (*child_node)[0] = (*child_node)[1]; (*child_node)[1] = tmp; } } index = child; curr_node = child_node; } } static void ih_impl_float_down_min(struct intervalheap * _heap_) { size_t index = 0; size_t(*curr_node)[2] = &(_heap_->buffer[index]); while (1) { if (2 * index + 1 >= _heap_->size) break; size_t child; size_t L_index = index * 2 + 1; size_t R_index = index * 2 + 2; if (R_index < _heap_->size) { 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; } else child = L_index; size_t(*child_node)[2] = &(_heap_->buffer[child]); if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) break; size_t tmp = (*child_node)[0]; (*child_node)[0] = (*curr_node)[0]; (*curr_node)[0] = tmp; if (child != _heap_->size - 1 || _heap_->count % 2 == 0) { if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) { tmp = (*child_node)[0]; (*child_node)[0] = (*child_node)[1]; (*child_node)[1] = tmp; } } index = child; curr_node = child_node; } } struct intervalheap_iter ih_iter_start(struct intervalheap * target) { struct intervalheap_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = ih_empty(target); return iter; } struct intervalheap_iter ih_iter_end(struct intervalheap * target) { struct intervalheap_iter iter; iter.target = target; iter.cursor = 0; iter.start = ih_empty(target); iter.end = 1; if (!ih_empty(target)) iter.cursor = target->count - 1; return iter; } _Bool ih_iter_at_start(struct intervalheap_iter * iter) { return ih_empty(iter->target) || iter->start; } _Bool ih_iter_at_end(struct intervalheap_iter * iter) { return ih_empty(iter->target) || iter->end; } _Bool ih_iter_to_start(struct intervalheap_iter * iter) { if (!ih_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = ih_empty(iter->target); return 1; } return 0; } _Bool ih_iter_to_end(struct intervalheap_iter * iter) { if (!ih_empty(iter->target)) { iter->cursor = iter->target->count - 1; iter->start = ih_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool ih_iter_next(struct intervalheap_iter * iter) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = ih_empty(iter->target); iter->cursor++; return 1; } _Bool ih_iter_prev(struct intervalheap_iter * iter) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } iter->end = ih_empty(iter->target); iter->cursor--; return 1; } _Bool ih_iter_advance(struct intervalheap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; if (iter->end) return 0; iter->start = ih_empty(iter->target); iter->cursor += steps; return 1; } _Bool ih_iter_rewind(struct intervalheap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->end = ih_empty(iter->target); iter->cursor -= steps; return 1; } _Bool ih_iter_go_to(struct intervalheap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return ih_iter_rewind(iter, iter->cursor - index); else if (iter->cursor < index) return ih_iter_advance(iter, index - iter->cursor); return 1; } size_t ih_iter_value(struct intervalheap_iter * iter) { if (ih_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; } size_t ih_iter_index(struct intervalheap_iter * iter) { return iter->cursor; } _Bool ih_to_string(struct intervalheap * _heap_, FILE * fptr) { struct intervalheap *h_ = _heap_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "size:%" "I64u" ", " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, h_->f_val, h_->alloc, (h_)->callbacks); } _Bool ih_print(struct intervalheap * _heap_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = 0; i < _heap_->count; i++) { if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) return 0; if (i + 1 < _heap_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_linkedlist.c b/tests/src/tst_cmc_linkedlist.c new file mode 100644 index 0000000..cbf5a65 --- /dev/null +++ b/tests/src/tst_cmc_linkedlist.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_linkedlist.h" + + + struct linkedlist *ll_new(struct linkedlist_fval * f_val) { return ll_new_custom(f_val, ((void *)0), ((void *)0)); } struct linkedlist *ll_new_custom(struct linkedlist_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist)); if (!_list_) return ((void *)0); _list_->count = 0; _list_->head = ((void *)0); _list_->tail = ((void *)0); _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; (_list_)->callbacks = callbacks; return _list_; } void ll_clear(struct linkedlist * _list_) { struct linkedlist_node *scan = _list_->head; while (_list_->head != ((void *)0)) { _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 = ((void *)0); _list_->tail = ((void *)0); _list_->flag = CMC_FLAG_OK; } 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) { ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool ll_push_front(struct linkedlist * _list_, size_t value) { struct linkedlist_node *_node_ = ll_new_node(_list_, value); if (!_node_) return 0; if (ll_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 1; } _Bool ll_push_at(struct linkedlist * _list_, size_t value, size_t index) { if (index > _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) { return ll_push_front(_list_, value); } else if (index == _list_->count) { return ll_push_back(_list_, value); } struct linkedlist_node *_node_ = ll_new_node(_list_, value); if (!_node_) return 0; struct linkedlist_node *scan = ll_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 1; } _Bool ll_push_back(struct linkedlist * _list_, size_t value) { struct linkedlist_node *_node_ = ll_new_node(_list_, value); if (!_node_) return 0; if (ll_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 1; } _Bool ll_pop_front(struct linkedlist * _list_) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } struct linkedlist_node *_node_ = _list_->head; _list_->head = _list_->head->next; _list_->alloc->free(_node_); if (_list_->head == ((void *)0)) _list_->tail = ((void *)0); else _list_->head->prev = ((void *)0); _list_->count--; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } _Bool ll_pop_at(struct linkedlist * _list_, size_t index) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) { return ll_pop_front(_list_); } else if (index == _list_->count - 1) { return ll_pop_back(_list_); } struct linkedlist_node *_node_ = ll_get_node(_list_, index); if (!_node_) return 0; _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 1; } _Bool ll_pop_back(struct linkedlist * _list_) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } struct linkedlist_node *_node_ = _list_->tail; _list_->tail = _list_->tail->prev; _list_->alloc->free(_node_); if (_list_->tail == ((void *)0)) _list_->head = ((void *)0); else _list_->tail->next = ((void *)0); _list_->count--; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } size_t ll_front(struct linkedlist * _list_) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->head->value; } size_t ll_get(struct linkedlist * _list_, size_t index) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } struct linkedlist_node *scan = ll_get_node(_list_, index); if (scan == ((void *)0)) return (size_t){ 0 }; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return scan->value; } size_t *ll_get_ref(struct linkedlist * _list_, size_t index) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } struct linkedlist_node *scan = ll_get_node(_list_, index); if (scan == ((void *)0)) return ((void *)0); if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return &(scan->value); } size_t ll_back(struct linkedlist * _list_) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->tail->value; } _Bool ll_contains(struct linkedlist * _list_, size_t value) { _list_->flag = CMC_FLAG_OK; _Bool result = 0; struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) { if (_list_->f_val->cmp(scan->value, value) == 0) { result = 1; break; } scan = scan->next; } if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return result; } _Bool ll_empty(struct linkedlist * _list_) { return _list_->count == 0; } size_t ll_count(struct linkedlist * _list_) { return _list_->count; } int ll_flag(struct linkedlist * _list_) { return _list_->flag; } struct linkedlist *ll_copy_of(struct linkedlist * _list_) { struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0)); if (!result) return ((void *)0); (result)->callbacks = _list_->callbacks; struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) { struct linkedlist_node * new_node; if (_list_->f_val->cpy) new_node = ll_new_node(_list_, _list_->f_val->cpy(scan->value)); else new_node = ll_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 ll_equals(struct linkedlist * _list1_, struct linkedlist * _list2_) { _list1_->flag = CMC_FLAG_OK; _list2_->flag = CMC_FLAG_OK; if (_list1_->count != _list2_->count) return 0; struct linkedlist_node *scan1 = _list1_->head; struct linkedlist_node *scan2 = _list2_->head; while (scan1 != ((void *)0) && scan2 != ((void *)0)) { if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) return 0; scan1 = scan1->next; scan2 = scan2->next; } return 1; } struct linkedlist_iter ll_iter_start(struct linkedlist * target) { struct linkedlist_iter iter; iter.target = target; iter.cursor = target->head; iter.index = 0; iter.start = 1; iter.end = ll_empty(target); return iter; } struct linkedlist_iter ll_iter_end(struct linkedlist * target) { struct linkedlist_iter iter; iter.target = target; iter.cursor = target->tail; iter.index = 0; iter.start = ll_empty(target); iter.end = 1; if (!ll_empty(target)) iter.index = target->count - 1; return iter; } _Bool ll_iter_at_start(struct linkedlist_iter * iter) { return ll_empty(iter->target) || iter->start; } _Bool ll_iter_at_end(struct linkedlist_iter * iter) { return ll_empty(iter->target) || iter->end; } _Bool ll_iter_to_start(struct linkedlist_iter * iter) { if (!ll_empty(iter->target)) { iter->cursor = iter->target->head; iter->index = 0; iter->start = 1; iter->end = ll_empty(iter->target); return 1; } return 0; } _Bool ll_iter_to_end(struct linkedlist_iter * iter) { if (!ll_empty(iter->target)) { iter->cursor = iter->target->tail; iter->index = iter->target->count - 1; iter->start = ll_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool ll_iter_next(struct linkedlist_iter * iter) { if (iter->end) return 0; if (iter->cursor->next == ((void *)0)) { iter->end = 1; return 0; } iter->start = ll_empty(iter->target); iter->cursor = iter->cursor->next; iter->index++; return 1; } _Bool ll_iter_prev(struct linkedlist_iter * iter) { if (iter->start) return 0; if (iter->cursor->prev == ((void *)0)) { iter->start = 1; return 0; } iter->end = ll_empty(iter->target); iter->cursor = iter->cursor->prev; iter->index--; return 1; } _Bool ll_iter_advance(struct linkedlist_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor->next == ((void *)0)) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; iter->start = ll_empty(iter->target); iter->index += steps; for (size_t i = 0; i < steps; i++) iter->cursor = iter->cursor->next; return 1; } _Bool ll_iter_rewind(struct linkedlist_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor->prev == ((void *)0)) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; iter->end = ll_empty(iter->target); iter->index -= steps; for (size_t i = 0; i < steps; i++) iter->cursor = iter->cursor->prev; return 1; } _Bool ll_iter_go_to(struct linkedlist_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return ll_iter_rewind(iter, iter->index - index); else if (iter->index < index) return ll_iter_advance(iter, index - iter->index); return 1; } size_t ll_iter_value(struct linkedlist_iter * iter) { if (ll_empty(iter->target)) return (size_t){ 0 }; return iter->cursor->value; } size_t *ll_iter_rvalue(struct linkedlist_iter * iter) { if (ll_empty(iter->target)) return ((void *)0); return &(iter->cursor->value); } size_t ll_iter_index(struct linkedlist_iter * iter) { return iter->index; } struct linkedlist_node * ll_iter_node(struct linkedlist_iter * iter) { return iter->cursor; } struct linkedlist_node * ll_new_node(struct linkedlist * _list_, size_t value) { struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node)); if (!_node_) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } _node_->value = value; _node_->next = ((void *)0); _node_->prev = ((void *)0); return _node_; } void ll_free_node(struct linkedlist * _list_, struct linkedlist_node * _node_) { _list_->alloc->free(_node_); } struct linkedlist_node * ll_head(struct linkedlist * _list_) { return _list_->head; } struct linkedlist_node * ll_get_node(struct linkedlist * _list_, size_t index) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } struct linkedlist_node *_node_ = ((void *)0); 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 linkedlist_node * ll_tail(struct linkedlist * _list_) { return _list_->tail; } _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) return 0; new_node->next = _node_->next; if (_node_->next != ((void *)0)) _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 1; } _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) return 0; new_node->prev = _node_->prev; if (_node_->prev != ((void *)0)) _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 1; } _Bool ll_del_next(struct linkedlist * _owner_, struct linkedlist_node * _node_) { if (_node_->next == ((void *)0)) { _owner_->flag = CMC_FLAG_INVALID; return 0; } struct linkedlist_node *tmp = _node_->next; _node_->next = _node_->next->next; if (tmp->next != ((void *)0)) tmp->next->prev = _node_; else _owner_->tail = _node_; _owner_->alloc->free(tmp); _owner_->count--; _owner_->flag = CMC_FLAG_OK; return 1; } _Bool ll_del_curr(struct linkedlist * _owner_, struct linkedlist_node * _node_) { if (_node_->prev != ((void *)0)) _node_->prev->next = _node_->next; else _owner_->head = _node_->next; if (_node_->next != ((void *)0)) _node_->next->prev = _node_->prev; else _owner_->tail = _node_->prev; _owner_->alloc->free(_node_); _owner_->count--; _owner_->flag = CMC_FLAG_OK; return 1; } _Bool ll_del_prev(struct linkedlist * _owner_, struct linkedlist_node * _node_) { if (_node_->prev == ((void *)0)) { _owner_->flag = CMC_FLAG_INVALID; return 0; } struct linkedlist_node *tmp = _node_->prev; _node_->prev = _node_->prev->prev; if (tmp->prev != ((void *)0)) tmp->prev->next = _node_; else _owner_->head = _node_; _owner_->alloc->free(tmp); _owner_->count--; _owner_->flag = CMC_FLAG_OK; return 1; } struct linkedlist_node * ll_next_node(struct linkedlist_node * _node_) { return _node_->next; } struct linkedlist_node * ll_prev_node(struct linkedlist_node * _node_) { return _node_->prev; } _Bool ll_to_string(struct linkedlist * _list_, FILE * fptr) { struct linkedlist *l_ = _list_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "count:%" "I64u" ", " "head:%p, " "tail:%p, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); } _Bool ll_print(struct linkedlist * _list_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) { if (!_list_->f_val->str(fptr, scan->value)) return 0; scan = scan->next; if (scan) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_list.c b/tests/src/tst_cmc_list.c new file mode 100644 index 0000000..a0061d8 --- /dev/null +++ b/tests/src/tst_cmc_list.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_list.h" + + + struct list *l_new(size_t capacity, struct list_fval * f_val) { return l_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct list *l_new_custom(size_t capacity, struct list_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct list *_list_ = alloc->malloc(sizeof(struct list)); if (!_list_) return ((void *)0); _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_list_->buffer) { alloc->free(_list_); return ((void *)0); } _list_->capacity = capacity; _list_->count = 0; _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; (_list_)->callbacks = callbacks; return _list_; } void l_clear(struct list * _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(size_t) * _list_->capacity); _list_->count = 0; _list_->flag = CMC_FLAG_OK; } void l_free(struct list * _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 l_customize(struct list * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool l_push_front(struct list * _list_, size_t value) { if (l_full(_list_)) { if (!l_resize(_list_, _list_->count * 2)) return 0; } if (!l_empty(_list_)) { memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(size_t)); } _list_->buffer[0] = value; _list_->count++; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_push_at(struct list * _list_, size_t value, size_t index) { if (index > _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } if (l_full(_list_)) { if (!l_resize(_list_, _list_->count * 2)) return 0; } 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; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_push_back(struct list * _list_, size_t value) { if (l_full(_list_)) { if (!l_resize(_list_, _list_->count * 2)) return 0; } _list_->buffer[_list_->count++] = value; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_pop_front(struct list * _list_) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } _Bool l_pop_at(struct list * _list_, size_t index) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } _Bool l_pop_back(struct list * _list_) { if (l_empty(_list_)) return 0; _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } size_t l_front(struct list * _list_) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[0]; } size_t l_get(struct list * _list_, size_t index) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[index]; } size_t *l_get_ref(struct list * _list_, size_t index) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return &(_list_->buffer[index]); } size_t l_back(struct list * _list_) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[_list_->count - 1]; } size_t l_index_of(struct list * _list_, size_t value, _Bool from_start) { _list_->flag = CMC_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 l_contains(struct list * _list_, size_t value) { _list_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _list_->count; i++) { if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) { result = 1; break; } } if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return result; } _Bool l_empty(struct list * _list_) { return _list_->count == 0; } _Bool l_full(struct list * _list_) { return _list_->count >= _list_->capacity; } size_t l_count(struct list * _list_) { return _list_->count; } _Bool l_fits(struct list * _list_, size_t size) { return _list_->count + size <= _list_->capacity; } size_t l_capacity(struct list * _list_) { return _list_->capacity; } int l_flag(struct list * _list_) { return _list_->flag; } _Bool l_resize(struct list * _list_, size_t capacity) { _list_->flag = CMC_FLAG_OK; if (_list_->capacity == capacity) return 1; if (capacity < _list_->count) { _list_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _list_->flag = CMC_FLAG_ALLOC; return 0; } _list_->buffer = new_buffer; _list_->capacity = capacity; if ((_list_)->callbacks && (_list_)->callbacks->resize) (_list_)->callbacks->resize();; return 1; } struct list *l_copy_of(struct list * _list_) { struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); if (!result) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } (result)->callbacks = _list_->callbacks; if (_list_->f_val->cpy) { for (size_t i = 0; i < _list_->count; i++) result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); } else memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); result->count = _list_->count; _list_->flag = CMC_FLAG_OK; return result; } _Bool l_equals(struct list * _list1_, struct list * _list2_) { _list1_->flag = CMC_FLAG_OK; _list2_->flag = CMC_FLAG_OK; if (_list1_->count != _list2_->count) return 0; for (size_t i = 0; i < _list1_->count; i++) { if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) return 0; } return 1; } struct list_iter l_iter_start(struct list * target) { struct list_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = l_empty(target); return iter; } struct list_iter l_iter_end(struct list * target) { struct list_iter iter; iter.target = target; iter.cursor = 0; iter.start = l_empty(target); iter.end = 1; if (!l_empty(target)) iter.cursor = target->count - 1; return iter; } _Bool l_iter_at_start(struct list_iter * iter) { return l_empty(iter->target) || iter->start; } _Bool l_iter_at_end(struct list_iter * iter) { return l_empty(iter->target) || iter->end; } _Bool l_iter_to_start(struct list_iter * iter) { if (!l_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = l_empty(iter->target); return 1; } return 0; } _Bool l_iter_to_end(struct list_iter * iter) { if (!l_empty(iter->target)) { iter->start = l_empty(iter->target); iter->cursor = iter->target->count - 1; iter->end = 1; return 1; } return 0; } _Bool l_iter_next(struct list_iter * iter) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = l_empty(iter->target); iter->cursor++; return 1; } _Bool l_iter_prev(struct list_iter * iter) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } iter->end = l_empty(iter->target); iter->cursor--; return 1; } _Bool l_iter_advance(struct list_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; iter->start = l_empty(iter->target); iter->cursor += steps; return 1; } _Bool l_iter_rewind(struct list_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->end = l_empty(iter->target); iter->cursor -= steps; return 1; } _Bool l_iter_go_to(struct list_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return l_iter_rewind(iter, iter->cursor - index); else if (iter->cursor < index) return l_iter_advance(iter, index - iter->cursor); return 1; } size_t l_iter_value(struct list_iter * iter) { if (l_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t *l_iter_rvalue(struct list_iter * iter) { if (l_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor]); } size_t l_iter_index(struct list_iter * iter) { return iter->cursor; } _Bool l_seq_push_front(struct list * _list_, size_t * values, size_t size) { if (size == 0) { _list_->flag = CMC_FLAG_INVALID; return 0; } if (!l_fits(_list_, size)) { if (!l_resize(_list_, _list_->count + size)) return 0; } memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); memcpy(_list_->buffer, values, size * sizeof(size_t)); _list_->count += size; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_seq_push_at(struct list * _list_, size_t * values, size_t size, size_t index) { if (size == 0) { _list_->flag = CMC_FLAG_INVALID; return 0; } if (index > _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) return l_seq_push_front(_list_, values, size); else if (index == _list_->count) return l_seq_push_back(_list_, values, size); if (!l_fits(_list_, size)) { if (!l_resize(_list_, _list_->count + size)) return 0; } memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); memcpy(_list_->buffer + index, values, size * sizeof(size_t)); _list_->count += size; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_seq_push_back(struct list * _list_, size_t * values, size_t size) { if (size == 0) { _list_->flag = CMC_FLAG_INVALID; return 0; } if (!l_fits(_list_, size)) { if (!l_resize(_list_, _list_->count + size)) return 0; } memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); _list_->count += size; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_seq_pop_at(struct list * _list_, size_t from, size_t to) { if (from > to) { _list_->flag = CMC_FLAG_INVALID; return 0; } if (to >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } size_t length = (to - from + 1); memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); _list_->count -= to - from + 1; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } struct list *l_seq_sublist(struct list * _list_, size_t from, size_t to) { if (from > to) { _list_->flag = CMC_FLAG_INVALID; return ((void *)0); } if (to >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } size_t length = to - from + 1; struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks); if (!result) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); _list_->count -= length; result->count = length; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return result; } _Bool l_to_string(struct list * _list_, FILE * fptr) { struct list *l_ = _list_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); } _Bool l_print(struct list * _list_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = 0; i < _list_->count; i++) { if (!_list_->f_val->str(fptr, _list_->buffer[i])) return 0; if (i + 1 < _list_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_queue.c b/tests/src/tst_cmc_queue.c new file mode 100644 index 0000000..9ae20dc --- /dev/null +++ b/tests/src/tst_cmc_queue.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_queue.h" + + + struct queue *q_new(size_t capacity, struct queue_fval * f_val) { return q_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct queue *q_new_custom(size_t capacity, struct queue_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct queue *_queue_ = alloc->malloc(sizeof(struct queue)); if (!_queue_) return ((void *)0); _queue_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_queue_->buffer) { alloc->free(_queue_); return ((void *)0); } _queue_->capacity = capacity; _queue_->count = 0; _queue_->front = 0; _queue_->back = 0; _queue_->flag = CMC_FLAG_OK; _queue_->f_val = f_val; _queue_->alloc = alloc; (_queue_)->callbacks = callbacks; return _queue_; } void q_clear(struct queue * _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(size_t) * _queue_->capacity); _queue_->count = 0; _queue_->front = 0; _queue_->back = 0; _queue_->flag = CMC_FLAG_OK; } void q_free(struct queue * _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 q_customize(struct queue * _queue_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _queue_->alloc = &cmc_alloc_node_default; else _queue_->alloc = alloc; (_queue_)->callbacks = callbacks; _queue_->flag = CMC_FLAG_OK; } _Bool q_enqueue(struct queue * _queue_, size_t value) { if (q_full(_queue_)) { if (!q_resize(_queue_, _queue_->capacity * 2)) return 0; } _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 1; } _Bool q_dequeue(struct queue * _queue_) { if (q_empty(_queue_)) { _queue_->flag = CMC_FLAG_EMPTY; return 0; } _queue_->buffer[_queue_->front] = (size_t){ 0 }; _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; _queue_->count--; _queue_->flag = CMC_FLAG_OK; if ((_queue_)->callbacks && (_queue_)->callbacks->delete) (_queue_)->callbacks->delete();; return 1; } size_t q_peek(struct queue * _queue_) { if (q_empty(_queue_)) { _queue_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _queue_->flag = CMC_FLAG_OK; if ((_queue_)->callbacks && (_queue_)->callbacks->read) (_queue_)->callbacks->read();; return _queue_->buffer[_queue_->front]; } _Bool q_contains(struct queue * _queue_, size_t value) { _queue_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) { if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) { result = 1; break; } i = (i + 1) % _queue_->capacity; } if ((_queue_)->callbacks && (_queue_)->callbacks->read) (_queue_)->callbacks->read();; return result; } _Bool q_empty(struct queue * _queue_) { return _queue_->count == 0; } _Bool q_full(struct queue * _queue_) { return _queue_->count >= _queue_->capacity; } size_t q_count(struct queue * _queue_) { return _queue_->count; } size_t q_capacity(struct queue * _queue_) { return _queue_->capacity; } int q_flag(struct queue * _queue_) { return _queue_->flag; } _Bool q_resize(struct queue * _queue_, size_t capacity) { if (_queue_->capacity == capacity) goto success; if (capacity < _queue_->count) { _queue_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _queue_->alloc->malloc(sizeof(size_t) * capacity); if (!new_buffer) { _queue_->flag = CMC_FLAG_ALLOC; return 0; } 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 1; } struct queue *q_copy_of(struct queue * _queue_) { struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0)); if (!result) { _queue_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _queue_->callbacks; if (_queue_->f_val->cpy) { for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) { 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 q_equals(struct queue * _queue1_, struct queue * _queue2_) { _queue1_->flag = CMC_FLAG_OK; _queue2_->flag = CMC_FLAG_OK; 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++) { if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) return 0; i = (i + 1) % _queue1_->capacity; j = (j + 1) % _queue2_->capacity; } return 1; } struct queue_iter q_iter_start(struct queue * target) { struct queue_iter iter; iter.target = target; iter.cursor = target->front; iter.index = 0; iter.start = 1; iter.end = q_empty(target); return iter; } struct queue_iter q_iter_end(struct queue * target) { struct queue_iter iter; iter.target = target; if (!q_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 = q_empty(target); iter.end = 1; return iter; } _Bool q_iter_at_start(struct queue_iter * iter) { return q_empty(iter->target) || iter->start; } _Bool q_iter_at_end(struct queue_iter * iter) { return q_empty(iter->target) || iter->end; } _Bool q_iter_to_start(struct queue_iter * iter) { if (!q_empty(iter->target)) { iter->cursor = iter->target->front; iter->index = 0; iter->start = 1; iter->end = 0; return 1; } return 0; } _Bool q_iter_to_end(struct queue_iter * iter) { if (!q_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 = 0; iter->end = 1; return 1; } return 0; } _Bool q_iter_next(struct queue_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = q_empty(iter->target); iter->cursor = (iter->cursor + 1) % (iter->target->capacity); iter->index++; return 1; } _Bool q_iter_prev(struct queue_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = q_empty(iter->target); iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; iter->index--; return 1; } _Bool q_iter_advance(struct queue_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; iter->start = q_empty(iter->target); iter->index += steps; iter->cursor = (iter->cursor + steps) % iter->target->capacity; return 1; } _Bool q_iter_rewind(struct queue_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; iter->end = q_empty(iter->target); iter->index -= steps; if (iter->cursor < steps) iter->cursor += iter->target->capacity; iter->cursor -= steps; return 1; } _Bool q_iter_go_to(struct queue_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return q_iter_rewind(iter, iter->index - index); else if (iter->index < index) return q_iter_advance(iter, index - iter->index); return 1; } size_t q_iter_value(struct queue_iter * iter) { if (q_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t *q_iter_rvalue(struct queue_iter * iter) { if (q_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor]); } size_t q_iter_index(struct queue_iter * iter) { return iter->index; } _Bool q_to_string(struct queue * _queue_, FILE * fptr) { struct queue *q_ = _queue_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "front:%" "I64u" ", " "back:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag, q_->f_val, q_->alloc, (q_)->callbacks); } _Bool q_print(struct queue * _queue_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) { if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) return 0; i = (i + 1) % _queue_->capacity; if (j + 1 < _queue_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_sortedlist.c b/tests/src/tst_cmc_sortedlist.c new file mode 100644 index 0000000..75c57f9 --- /dev/null +++ b/tests/src/tst_cmc_sortedlist.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_sortedlist.h" + + + 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) { return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist)); if (!_list_) return ((void *)0); _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_list_->buffer) { alloc->free(_list_); return ((void *)0); } _list_->capacity = capacity; _list_->count = 0; _list_->is_sorted = 0; _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; (_list_)->callbacks = callbacks; return _list_; } void sl_clear(struct sortedlist * _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(size_t) * _list_->capacity); _list_->count = 0; _list_->flag = CMC_FLAG_OK; } void sl_free(struct sortedlist * _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 sl_customize(struct sortedlist * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool sl_insert(struct sortedlist * _list_, size_t value) { if (sl_full(_list_)) { if (!sl_resize(_list_, _list_->capacity * 2)) return 0; } _list_->buffer[_list_->count++] = value; _list_->is_sorted = 0; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool sl_remove(struct sortedlist * _list_, size_t index) { if (sl_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } size_t sl_max(struct sortedlist * _list_) { if (sl_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[_list_->count - 1]; } size_t sl_min(struct sortedlist * _list_) { if (sl_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[0]; } size_t sl_get(struct sortedlist * _list_, size_t index) { if (sl_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[index]; } size_t sl_index_of(struct sortedlist * _list_, size_t value, _Bool from_start) { _list_->flag = CMC_FLAG_OK; sl_sort(_list_); if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; if (from_start) { return sl_impl_binary_search_first(_list_, value); } return sl_impl_binary_search_last(_list_, value); } _Bool sl_contains(struct sortedlist * _list_, size_t value) { _list_->flag = CMC_FLAG_OK; if (sl_empty(_list_)) return 0; sl_sort(_list_); if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return sl_impl_binary_search_first(_list_, value) < _list_->count; } _Bool sl_empty(struct sortedlist * _list_) { return _list_->count == 0; } _Bool sl_full(struct sortedlist * _list_) { return _list_->count >= _list_->capacity; } size_t sl_count(struct sortedlist * _list_) { return _list_->count; } size_t sl_capacity(struct sortedlist * _list_) { return _list_->capacity; } int sl_flag(struct sortedlist * _list_) { return _list_->flag; } _Bool sl_resize(struct sortedlist * _list_, size_t capacity) { if (_list_->capacity == capacity) goto success; if (capacity < _list_->count) { _list_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _list_->flag = CMC_FLAG_ALLOC; return 0; } _list_->buffer = new_buffer; _list_->capacity = capacity; success: _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->resize) (_list_)->callbacks->resize();; return 1; } void sl_sort(struct sortedlist * _list_) { _list_->flag = CMC_FLAG_OK; if (!_list_->is_sorted && _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, ((void *)0)); if (!result) { _list_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _list_->callbacks; if (_list_->f_val->cpy) { for (size_t i = 0; i < _list_->count; i++) result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); } else memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); result->count = _list_->count; _list_->flag = CMC_FLAG_OK; return result; } _Bool sl_equals(struct sortedlist * _list1_, struct sortedlist * _list2_) { if (_list1_->count != _list2_->count) return 0; sl_sort(_list1_); sl_sort(_list2_); for (size_t i = 0; i < _list1_->count; i++) { if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) return 0; } return 1; } static size_t sl_impl_binary_search_first(struct sortedlist * _list_, size_t value) { if (sl_empty(_list_)) return 1; size_t L = 0; size_t R = _list_->count; while (L < R) { size_t M = L + (R - L) / 2; if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) L = M + 1; else R = M; } if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) return L; return _list_->count; } static size_t sl_impl_binary_search_last(struct sortedlist * _list_, size_t value) { if (sl_empty(_list_)) return 1; size_t L = 0; size_t R = _list_->count; while (L < R) { size_t M = L + (R - L) / 2; if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) R = M; else L = M + 1; } if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) return L - 1; return _list_->count; } void sl_impl_sort_quicksort(size_t * array, int (*cmp)(size_t, size_t), size_t low, size_t high) { while (low < high) { if (high - low < 10) { sl_impl_sort_insertion(array, cmp, low, high); break; } else { size_t pivot = array[high]; size_t pindex = low; for (size_t i = low; i < high; i++) { if (cmp(array[i], pivot) <= 0) { size_t _tmp_ = array[i]; array[i] = array[pindex]; array[pindex] = _tmp_; pindex++; } } size_t _tmp_ = array[pindex]; array[pindex] = array[high]; array[high] = _tmp_; if (pindex - low < high - pindex) { sl_impl_sort_quicksort (array, cmp, low, pindex - 1); low = pindex + 1; } else { sl_impl_sort_quicksort (array, cmp, pindex + 1, high); high = pindex - 1; } } } } void sl_impl_sort_insertion(size_t * array, int (*cmp)(size_t, size_t), size_t low, size_t high) { for (size_t i = low + 1; i <= high; i++) { size_t _tmp_ = array[i]; size_t j = i; while (j > low && cmp(array[j - 1], _tmp_) > 0) { array[j] = array[j - 1]; j--; } array[j] = _tmp_; } } struct sortedlist_iter sl_iter_start(struct sortedlist * target) { sl_sort(target); struct sortedlist_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = sl_empty(target); return iter; } struct sortedlist_iter sl_iter_end(struct sortedlist * target) { sl_sort(target); struct sortedlist_iter iter; iter.target = target; iter.cursor = 0; iter.start = sl_empty(target); iter.end = 1; if (!sl_empty(target)) iter.cursor = target->count - 1; return iter; } _Bool sl_iter_at_start(struct sortedlist_iter * iter) { return sl_empty(iter->target) || iter->start; } _Bool sl_iter_at_end(struct sortedlist_iter * iter) { return sl_empty(iter->target) || iter->end; } _Bool sl_iter_to_start(struct sortedlist_iter * iter) { if (!sl_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = sl_empty(iter->target); return 1; } return 0; } _Bool sl_iter_to_end(struct sortedlist_iter * iter) { if (!sl_empty(iter->target)) { iter->start = sl_empty(iter->target); iter->cursor = iter->target->count - 1; iter->end = 1; return 1; } return 0; } _Bool sl_iter_next(struct sortedlist_iter * iter) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = sl_empty(iter->target); iter->cursor++; return 1; } _Bool sl_iter_prev(struct sortedlist_iter * iter) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } iter->end = sl_empty(iter->target); iter->cursor--; return 1; } _Bool sl_iter_advance(struct sortedlist_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; iter->start = sl_empty(iter->target); iter->cursor += steps; return 1; } _Bool sl_iter_rewind(struct sortedlist_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->end = sl_empty(iter->target); iter->cursor -= steps; return 1; } _Bool sl_iter_go_to(struct sortedlist_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return sl_iter_rewind(iter, iter->cursor - index); else if (iter->cursor < index) return sl_iter_advance(iter, index - iter->cursor); return 1; } size_t sl_iter_value(struct sortedlist_iter * iter) { if (sl_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t sl_iter_index(struct sortedlist_iter * iter) { return iter->cursor; } _Bool sl_to_string(struct sortedlist * _list_, FILE * fptr) { struct sortedlist *l_ = _list_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "is_sorted:%s, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); } _Bool sl_print(struct sortedlist * _list_, FILE * fptr, const char *start, const char *separator, const char *end) { sl_sort(_list_); fprintf(fptr, "%s", start); for (size_t i = 0; i < _list_->count; i++) { if (!_list_->f_val->str(fptr, _list_->buffer[i])) return 0; if (i + 1 < _list_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_stack.c b/tests/src/tst_cmc_stack.c new file mode 100644 index 0000000..16f8bf8 --- /dev/null +++ b/tests/src/tst_cmc_stack.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_stack.h" + + + struct stack *s_new(size_t capacity, struct stack_fval * f_val) { return s_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct stack *s_new_custom(size_t capacity, struct stack_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct stack *_stack_ = alloc->malloc(sizeof(struct stack)); if (!_stack_) return ((void *)0); _stack_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_stack_->buffer) { alloc->free(_stack_); return ((void *)0); } _stack_->capacity = capacity; _stack_->count = 0; _stack_->flag = CMC_FLAG_OK; _stack_->f_val = f_val; _stack_->alloc = alloc; (_stack_)->callbacks = callbacks; return _stack_; } void s_clear(struct stack * _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(size_t) * _stack_->capacity); _stack_->count = 0; _stack_->flag = CMC_FLAG_OK; } void s_free(struct stack * _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 s_customize(struct stack * _stack_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _stack_->alloc = &cmc_alloc_node_default; else _stack_->alloc = alloc; (_stack_)->callbacks = callbacks; _stack_->flag = CMC_FLAG_OK; } _Bool s_push(struct stack * _stack_, size_t value) { if (s_full(_stack_)) { if (!s_resize(_stack_, _stack_->capacity * 2)) return 0; } _stack_->buffer[_stack_->count++] = value; _stack_->flag = CMC_FLAG_OK; if ((_stack_)->callbacks && (_stack_)->callbacks->create) (_stack_)->callbacks->create();; return 1; } _Bool s_pop(struct stack * _stack_) { if (s_empty(_stack_)) { _stack_->flag = CMC_FLAG_EMPTY; return 0; } _stack_->buffer[--_stack_->count] = (size_t){ 0 }; _stack_->flag = CMC_FLAG_OK; if ((_stack_)->callbacks && (_stack_)->callbacks->delete) (_stack_)->callbacks->delete();; return 1; } size_t s_top(struct stack * _stack_) { if (s_empty(_stack_)) { _stack_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _stack_->flag = CMC_FLAG_OK; if ((_stack_)->callbacks && (_stack_)->callbacks->read) (_stack_)->callbacks->read();; return _stack_->buffer[_stack_->count - 1]; } _Bool s_contains(struct stack * _stack_, size_t value) { _stack_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _stack_->count; i++) { if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) { result = 1; break; } } if ((_stack_)->callbacks && (_stack_)->callbacks->read) (_stack_)->callbacks->read();; return result; } _Bool s_empty(struct stack * _stack_) { return _stack_->count == 0; } _Bool s_full(struct stack * _stack_) { return _stack_->count >= _stack_->capacity; } size_t s_count(struct stack * _stack_) { return _stack_->count; } size_t s_capacity(struct stack * _stack_) { return _stack_->capacity; } int s_flag(struct stack * _stack_) { return _stack_->flag; } _Bool s_resize(struct stack * _stack_, size_t capacity) { if (_stack_->capacity == capacity) goto success; if (capacity < _stack_->count) { _stack_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _stack_->flag = CMC_FLAG_ALLOC; return 0; } _stack_->buffer = new_buffer; _stack_->capacity = capacity; success: _stack_->flag = CMC_FLAG_OK; if ((_stack_)->callbacks && (_stack_)->callbacks->resize) (_stack_)->callbacks->resize();; return 1; } struct stack *s_copy_of(struct stack * _stack_) { struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0)); if (!result) { _stack_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _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(size_t) * _stack_->count); result->count = _stack_->count; _stack_->flag = CMC_FLAG_OK; return result; } _Bool s_equals(struct stack * _stack1_, struct stack * _stack2_) { _stack1_->flag = CMC_FLAG_OK; _stack2_->flag = CMC_FLAG_OK; if (_stack1_->count != _stack2_->count) return 0; for (size_t i = 0; i < _stack1_->count; i++) { if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) return 0; } return 1; } struct stack_iter s_iter_start(struct stack * target) { struct stack_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = s_empty(target); if (!s_empty(target)) iter.cursor = target->count - 1; return iter; } struct stack_iter s_iter_end(struct stack * target) { struct stack_iter iter; iter.target = target; iter.cursor = 0; iter.start = s_empty(target); iter.end = 1; return iter; } _Bool s_iter_at_start(struct stack_iter * iter) { return s_empty(iter->target) || iter->start; } _Bool s_iter_at_end(struct stack_iter * iter) { return s_empty(iter->target) || iter->end; } _Bool s_iter_to_start(struct stack_iter * iter) { if (!s_empty(iter->target)) { iter->cursor = iter->target->count - 1; iter->start = 1; iter->end = s_empty(iter->target); return 1; } return 0; } _Bool s_iter_to_end(struct stack_iter * iter) { if (!s_empty(iter->target)) { iter->cursor = 0; iter->start = s_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool s_iter_next(struct stack_iter * iter) { if (iter->end) return 0; if (iter->cursor == 0) { iter->end = 1; return 0; } iter->start = s_empty(iter->target); iter->cursor--; return 1; } _Bool s_iter_prev(struct stack_iter * iter) { if (iter->start) return 0; if (iter->cursor + 1 == iter->target->count) { iter->start = 1; return 0; } iter->end = s_empty(iter->target); iter->cursor++; return 1; } _Bool s_iter_advance(struct stack_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor == 0) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->start = s_empty(iter->target); iter->cursor -= steps; return 1; } _Bool s_iter_rewind(struct stack_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor + 1 == iter->target->count) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; iter->end = s_empty(iter->target); iter->cursor += steps; return 1; } _Bool s_iter_go_to(struct stack_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return s_iter_advance(iter, iter->cursor - index); else if (iter->cursor < index) return s_iter_rewind(iter, index - iter->cursor); return 1; } size_t s_iter_value(struct stack_iter * iter) { if (s_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t *s_iter_rvalue(struct stack_iter * iter) { if (s_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor]); } size_t s_iter_index(struct stack_iter * iter) { if (s_empty(iter->target)) return 0; return iter->target->count - 1 - iter->cursor; } _Bool s_to_string(struct stack * _stack_, FILE * fptr) { struct stack *s_ = _stack_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); } _Bool s_print(struct stack * _stack_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = _stack_->count; i > 0; i--) { if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) return 0; if (i - 1 != 0) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_treemap.c b/tests/src/tst_cmc_treemap.c new file mode 100644 index 0000000..b6e2f5c --- /dev/null +++ b/tests/src/tst_cmc_treemap.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_treemap.h" + + + 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); static void tm_impl_rotate_right(struct treemap_node * *Z); static void tm_impl_rotate_left(struct treemap_node * *Z); static void tm_impl_rebalance(struct treemap * _map_, struct treemap_node * node); struct treemap *tm_new(struct treemap_fkey * f_key, struct treemap_fval * f_val) { return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0)); } struct treemap *tm_new_custom(struct treemap_fkey * f_key, struct treemap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!f_key || !f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct treemap *_map_ = alloc->malloc(sizeof(struct treemap)); if (!_map_) return ((void *)0); _map_->count = 0; _map_->root = ((void *)0); _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; (_map_)->callbacks = callbacks; return _map_; } void tm_clear(struct treemap * _map_) { struct treemap_node *scan = _map_->root; struct treemap_node *up = ((void *)0); while (scan != ((void *)0)) { if (scan->left != ((void *)0)) { struct treemap_node *left = scan->left; scan->left = up; up = scan; scan = left; } else if (scan->right != ((void *)0)) { struct treemap_node *right = scan->right; scan->left = up; scan->right = ((void *)0); up = scan; scan = right; } else { if (up == ((void *)0)) { 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 = ((void *)0); } while (up != ((void *)0)) { 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 != ((void *)0)) { scan = up->right; up->right = ((void *)0); break; } else { scan = up; up = up->left; } } } } _map_->count = 0; _map_->root = ((void *)0); _map_->flag = CMC_FLAG_OK; } 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) { ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool tm_insert(struct treemap * _map_, size_t key, size_t value) { if (tm_empty(_map_)) { _map_->root = tm_impl_new_node(_map_, key, value); if (!_map_->root) { _map_->flag = CMC_FLAG_ALLOC; return 0; } } else { struct treemap_node *scan = _map_->root; struct treemap_node *parent = scan; while (scan != ((void *)0)) { 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 0; } } struct treemap_node * node; if (_map_->f_key->cmp(parent->key, key) > 0) { parent->left = tm_impl_new_node(_map_, key, value); if (!parent->left) { _map_->flag = CMC_FLAG_ALLOC; return 0; } parent->left->parent = parent; node = parent->left; } else { parent->right = tm_impl_new_node(_map_, key, value); if (!parent->right) { _map_->flag = CMC_FLAG_ALLOC; return 0; } parent->right->parent = parent; node = parent->right; } tm_impl_rebalance(_map_, node); } _map_->count++; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->create) (_map_)->callbacks->create();; return 1; } _Bool tm_update(struct treemap * _map_, size_t key, size_t new_value, size_t * old_value) { struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } 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 1; } _Bool tm_remove(struct treemap * _map_, size_t key, size_t * out_value) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_value) *out_value = node->value; struct treemap_node *temp = ((void *)0), *unbalanced = ((void *)0); _Bool is_root = node->parent == ((void *)0); if (node->left == ((void *)0) && node->right == ((void *)0)) { if (is_root) _map_->root = ((void *)0); else { unbalanced = node->parent; if (node->parent->right == node) node->parent->right = ((void *)0); else node->parent->left = ((void *)0); } _map_->alloc->free(node); } else if (node->left == ((void *)0)) { if (is_root) { _map_->root = node->right; _map_->root->parent = ((void *)0); } 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 == ((void *)0)) { if (is_root) { _map_->root = node->left; _map_->root->parent = ((void *)0); } 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 != ((void *)0)) temp = temp->left; size_t temp_key = temp->key; size_t temp_val = temp->value; unbalanced = temp->parent; if (temp->left == ((void *)0) && temp->right == ((void *)0)) { if (temp->parent->right == temp) temp->parent->right = ((void *)0); else temp->parent->left = ((void *)0); } else if (temp->left == ((void *)0)) { 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 == ((void *)0)) { 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 != ((void *)0)) tm_impl_rebalance(_map_, unbalanced); if (_map_->count == 0) _map_->root = ((void *)0); _map_->count--; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->delete) (_map_)->callbacks->delete();; return 1; } _Bool tm_max(struct treemap * _map_, size_t * key, size_t * value) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *scan = _map_->root; while (scan->right != ((void *)0)) 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 1; } _Bool tm_min(struct treemap * _map_, size_t * key, size_t * value) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *scan = _map_->root; while (scan->left != ((void *)0)) 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 1; } size_t tm_get(struct treemap * _map_, size_t key) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return node->value; } size_t *tm_get_ref(struct treemap * _map_, size_t key) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return ((void *)0); } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return &(node->value); } _Bool tm_contains(struct treemap * _map_, size_t key) { _Bool result = tm_impl_get_node(_map_, key) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool tm_empty(struct treemap * _map_) { return _map_->count == 0; } size_t tm_count(struct treemap * _map_) { return _map_->count; } int tm_flag(struct treemap * _map_) { return _map_->flag; } struct treemap *tm_copy_of(struct treemap * _map_) { struct treemap *result = tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } struct treemap_node *root = _map_->root; _Bool left_done = 0; while (root) { if (!left_done) { while (root->left) root = root->left; } size_t key; size_t value; if (_map_->f_key->cpy) key = _map_->f_key->cpy(root->key); else key = root->key; if (_map_->f_val->cpy) value = _map_->f_val->cpy(root->value); else value = root->value; tm_insert(result, key, value); 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; } _map_->flag = CMC_FLAG_OK; (result)->callbacks = _map_->callbacks; return result; } _Bool tm_equals(struct treemap * _map1_, struct treemap * _map2_) { _map1_->flag = CMC_FLAG_OK; _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct treemap_node *root = _map1_->root; _Bool left_done = 0; while (root) { if (!left_done) { while (root->left) root = root->left; } struct treemap_node *node = tm_impl_get_node(_map2_, root->key); if (node == ((void *)0)) return 0; if (_map1_->f_val->cmp(node->value, root->value) != 0) 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; } static struct treemap_node * tm_impl_new_node(struct treemap * _map_, size_t key, size_t value) { struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); if (!node) return ((void *)0); node->key = key; node->value = value; node->right = ((void *)0); node->left = ((void *)0); node->parent = ((void *)0); node->height = 0; return node; } static struct treemap_node * tm_impl_get_node(struct treemap * _map_, size_t key) { struct treemap_node *scan = _map_->root; while (scan != ((void *)0)) { if (_map_->f_key->cmp(scan->key, key) > 0) scan = scan->left; else if (_map_->f_key->cmp(scan->key, key) < 0) scan = scan->right; else return scan; } return ((void *)0); } static unsigned char tm_impl_h(struct treemap_node * node) { if (node == ((void *)0)) return 0; return node->height; } static unsigned char tm_impl_hupdate(struct treemap_node * node) { if (node == ((void *)0)) return 0; unsigned char h_l = tm_impl_h(node->left); unsigned char h_r = tm_impl_h(node->right); return 1 + (h_l > h_r ? h_l : h_r); } static void tm_impl_rotate_right(struct treemap_node * *Z) { struct treemap_node *root = *Z; struct treemap_node *new_root = root->left; if (root->parent != ((void *)0)) { if (root->parent->left == root) root->parent->left = new_root; else root->parent->right = new_root; } new_root->parent = root->parent; root->parent = new_root; root->left = new_root->right; if (root->left) root->left->parent = root; new_root->right = root; root->height = tm_impl_hupdate(root); new_root->height = tm_impl_hupdate(new_root); *Z = new_root; } static void tm_impl_rotate_left(struct treemap_node * *Z) { struct treemap_node *root = *Z; struct treemap_node *new_root = root->right; if (root->parent != ((void *)0)) { if (root->parent->right == root) root->parent->right = new_root; else root->parent->left = new_root; } new_root->parent = root->parent; root->parent = new_root; root->right = new_root->left; if (root->right) root->right->parent = root; new_root->left = root; root->height = tm_impl_hupdate(root); new_root->height = tm_impl_hupdate(new_root); *Z = new_root; } static void tm_impl_rebalance(struct treemap * _map_, struct treemap_node * node) { struct treemap_node *scan = node, *child = ((void *)0); int balance; _Bool is_root = 0; while (scan != ((void *)0)) { if (scan->parent == ((void *)0)) is_root = 1; scan->height = tm_impl_hupdate(scan); balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); if (balance >= 2) { child = scan->right; if (tm_impl_h(child->right) < tm_impl_h(child->left)) tm_impl_rotate_right(&(scan->right)); tm_impl_rotate_left(&scan); } else if (balance <= -2) { child = scan->left; if (tm_impl_h(child->left) < tm_impl_h(child->right)) tm_impl_rotate_left(&(scan->left)); tm_impl_rotate_right(&scan); } if (is_root) { _map_->root = scan; is_root = 0; } scan = scan->parent; } } struct treemap_iter tm_iter_start(struct treemap * target) { struct treemap_iter iter; iter.target = target; iter.cursor = target->root; iter.first = ((void *)0); iter.last = ((void *)0); iter.index = 0; iter.start = 1; iter.end = tm_empty(target); if (!tm_empty(target)) { while (iter.cursor->left != ((void *)0)) iter.cursor = iter.cursor->left; iter.first = iter.cursor; iter.last = target->root; while (iter.last->right != ((void *)0)) iter.last = iter.last->right; } return iter; } struct treemap_iter tm_iter_end(struct treemap * target) { struct treemap_iter iter; iter.target = target; iter.cursor = target->root; iter.first = ((void *)0); iter.last = ((void *)0); iter.index = 0; iter.start = tm_empty(target); iter.end = 1; if (!tm_empty(target)) { while (iter.cursor->right != ((void *)0)) iter.cursor = iter.cursor->right; iter.last = iter.cursor; iter.first = target->root; while (iter.first->left != ((void *)0)) iter.first = iter.first->left; iter.index = target->count - 1; } return iter; } _Bool tm_iter_at_start(struct treemap_iter * iter) { return tm_empty(iter->target) || iter->start; } _Bool tm_iter_at_end(struct treemap_iter * iter) { return tm_empty(iter->target) || iter->end; } _Bool tm_iter_to_start(struct treemap_iter * iter) { if (!tm_empty(iter->target)) { iter->index = 0; iter->start = 1; iter->end = tm_empty(iter->target); iter->cursor = iter->first; return 1; } return 0; } _Bool tm_iter_to_end(struct treemap_iter * iter) { if (!tm_empty(iter->target)) { iter->index = iter->target->count - 1; iter->start = tm_empty(iter->target); iter->end = 1; iter->cursor = iter->last; return 1; } return 0; } _Bool tm_iter_next(struct treemap_iter * iter) { if (iter->end) return 0; if (iter->cursor == iter->last) { iter->end = 1; return 0; } iter->start = tm_empty(iter->target); if (iter->cursor->right != ((void *)0)) { iter->cursor = iter->cursor->right; while (iter->cursor->left != ((void *)0)) iter->cursor = iter->cursor->left; iter->index++; return 1; } while (1) { if (iter->cursor->parent->left == iter->cursor) { iter->cursor = iter->cursor->parent; iter->index++; return 1; } iter->cursor = iter->cursor->parent; } } _Bool tm_iter_prev(struct treemap_iter * iter) { if (iter->start) return 0; if (iter->cursor == iter->first) { iter->start = 1; return 0; } iter->end = tm_empty(iter->target); if (iter->cursor->left != ((void *)0)) { iter->cursor = iter->cursor->left; while (iter->cursor->right != ((void *)0)) iter->cursor = iter->cursor->right; iter->index--; return 1; } while (1) { if (iter->cursor->parent->right == iter->cursor) { iter->cursor = iter->cursor->parent; iter->index--; return 1; } iter->cursor = iter->cursor->parent; } } _Bool tm_iter_advance(struct treemap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor == iter->last) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) tm_iter_next(iter); return 1; } _Bool tm_iter_rewind(struct treemap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == iter->first) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) tm_iter_prev(iter); return 1; } _Bool tm_iter_go_to(struct treemap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return tm_iter_rewind(iter, iter->index - index); else if (iter->index < index) return tm_iter_advance(iter, index - iter->index); return 1; } size_t tm_iter_key(struct treemap_iter * iter) { if (tm_empty(iter->target)) return (size_t){ 0 }; return iter->cursor->key; } size_t tm_iter_value(struct treemap_iter * iter) { if (tm_empty(iter->target)) return (size_t){ 0 }; return iter->cursor->value; } size_t *tm_iter_rvalue(struct treemap_iter * iter) { if (tm_empty(iter->target)) return ((void *)0); return &(iter->cursor->value); } size_t tm_iter_index(struct treemap_iter * iter) { return iter->index; } _Bool tm_to_string(struct treemap * _map_, FILE * fptr) { struct treemap *m_ = _map_; return 0 <= fprintf(fptr, "struct %s<%s, %s> " "at %p { " "root:%p, " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "f_key:%p, " "alloc:%p, " "callbacks:%p }", "treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } _Bool tm_print(struct treemap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep) { fprintf(fptr, "%s", start); struct treemap_node *root = _map_->root; _Bool left_done = 0; size_t i = 0; while (root) { if (!left_done) { while (root->left) root = root->left; } if (!_map_->f_key->str(fptr, root->key)) return 0; fprintf(fptr, "%s", key_val_sep); if (!_map_->f_val->str(fptr, root->value)) return 0; if (++i < _map_->count) fprintf(fptr, "%s", separator); left_done = 1; if (root->right) { left_done = 0; root = root->right; } else if (root->parent) { while (root->parent && root == root->parent->right) root = root->parent; if (!root->parent) break; root = root->parent; } else break; } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/src/tst_cmc_treeset.c b/tests/src/tst_cmc_treeset.c new file mode 100644 index 0000000..1b46b22 --- /dev/null +++ b/tests/src/tst_cmc_treeset.c @@ -0,0 +1,7 @@ + + #include "tst_cmc_treeset.h" + + + 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); static void ts_impl_rotate_left(struct treeset_node * *Z); static void ts_impl_rebalance(struct treeset * _set_, struct treeset_node * node); struct treeset *ts_new(struct treeset_fval * f_val) { return ts_new_custom(f_val, ((void *)0), ((void *)0)); } struct treeset *ts_new_custom(struct treeset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct treeset *_set_ = alloc->malloc(sizeof(struct treeset)); if (!_set_) return ((void *)0); _set_->count = 0; _set_->root = ((void *)0); _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; (_set_)->callbacks = callbacks; return _set_; } void ts_clear(struct treeset * _set_) { struct treeset_node *scan = _set_->root; struct treeset_node *up = ((void *)0); while (scan != ((void *)0)) { if (scan->left != ((void *)0)) { struct treeset_node *left = scan->left; scan->left = up; up = scan; scan = left; } else if (scan->right != ((void *)0)) { struct treeset_node *right = scan->right; scan->left = up; scan->right = ((void *)0); up = scan; scan = right; } else { if (up == ((void *)0)) { if (_set_->f_val->free) _set_->f_val->free(scan->value); _set_->alloc->free(scan); scan = ((void *)0); } while (up != ((void *)0)) { if (_set_->f_val->free) _set_->f_val->free(scan->value); _set_->alloc->free(scan); if (up->right != ((void *)0)) { scan = up->right; up->right = ((void *)0); break; } else { scan = up; up = up->left; } } } } _set_->count = 0; _set_->root = ((void *)0); _set_->flag = CMC_FLAG_OK; } 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) { ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool ts_insert(struct treeset * _set_, size_t value) { if (ts_empty(_set_)) { _set_->root = ts_impl_new_node(_set_, value); if (!_set_->root) { _set_->flag = CMC_FLAG_ALLOC; return 0; } } else { struct treeset_node *scan = _set_->root; struct treeset_node *parent = scan; while (scan != ((void *)0)) { 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 0; } } struct treeset_node * node; if (_set_->f_val->cmp(parent->value, value) > 0) { parent->left = ts_impl_new_node(_set_, value); if (!parent->left) { _set_->flag = CMC_FLAG_ALLOC; return 0; } parent->left->parent = parent; node = parent->left; } else { parent->right = ts_impl_new_node(_set_, value); if (!parent->right) { _set_->flag = CMC_FLAG_ALLOC; return 0; } parent->right->parent = parent; node = parent->right; } ts_impl_rebalance(_set_, node); } _set_->count++; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->create) (_set_)->callbacks->create();; return 1; } _Bool ts_remove(struct treeset * _set_, size_t value) { if (ts_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *node = ts_impl_get_node(_set_, value); if (!node) { _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } struct treeset_node *temp = ((void *)0), *unbalanced = ((void *)0); _Bool is_root = node->parent == ((void *)0); if (node->left == ((void *)0) && node->right == ((void *)0)) { if (is_root) _set_->root = ((void *)0); else { unbalanced = node->parent; if (node->parent->right == node) node->parent->right = ((void *)0); else node->parent->left = ((void *)0); } _set_->alloc->free(node); } else if (node->left == ((void *)0)) { if (is_root) { _set_->root = node->right; _set_->root->parent = ((void *)0); } 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 == ((void *)0)) { if (is_root) { _set_->root = node->left; _set_->root->parent = ((void *)0); } 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 != ((void *)0)) temp = temp->left; size_t temp_value = temp->value; unbalanced = temp->parent; if (temp->left == ((void *)0) && temp->right == ((void *)0)) { if (temp->parent->right == temp) temp->parent->right = ((void *)0); else temp->parent->left = ((void *)0); } else if (temp->left == ((void *)0)) { 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 == ((void *)0)) { 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 != ((void *)0)) ts_impl_rebalance(_set_, unbalanced); if (_set_->count == 0) _set_->root = ((void *)0); _set_->count--; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->delete) (_set_)->callbacks->delete();; return 1; } _Bool ts_max(struct treeset * _set_, size_t * value) { if (ts_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *scan = _set_->root; while (scan->right != ((void *)0)) scan = scan->right; if (value) *value = scan->value; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool ts_min(struct treeset * _set_, size_t * value) { if (ts_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *scan = _set_->root; while (scan->left != ((void *)0)) scan = scan->left; if (value) *value = scan->value; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool ts_contains(struct treeset * _set_, size_t value) { _Bool result = ts_impl_get_node(_set_, value) != ((void *)0); if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return result; } _Bool ts_empty(struct treeset * _set_) { return _set_->count == 0; } size_t ts_count(struct treeset * _set_) { return _set_->count; } int ts_flag(struct treeset * _set_) { return _set_->flag; } struct treeset *ts_copy_of(struct treeset * _set_) { struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _set_->callbacks; if (!ts_empty(_set_)) { struct treeset_iter iter = ts_iter_start(_set_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { if (_set_->f_val->cpy) ts_insert (result, _set_->f_val->cpy(ts_iter_value(&iter))); else ts_insert(result, ts_iter_value(&iter)); } } _set_->flag = CMC_FLAG_OK; return result; } _Bool ts_equals(struct treeset * _set1_, struct treeset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { if (ts_impl_get_node(_set2_, ts_iter_value(&iter)) == ((void *)0)) return 0; } return 1; } 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)); if (!node) return ((void *)0); node->value = value; node->right = ((void *)0); node->left = ((void *)0); node->parent = ((void *)0); node->height = 0; return node; } static struct treeset_node * ts_impl_get_node(struct treeset * _set_, size_t value) { struct treeset_node *scan = _set_->root; while (scan != ((void *)0)) { 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 ((void *)0); } static unsigned char ts_impl_h(struct treeset_node * node) { if (node == ((void *)0)) return 0; return node->height; } static unsigned char ts_impl_hupdate(struct treeset_node * node) { if (node == ((void *)0)) return 0; unsigned char h_l = ts_impl_h(node->left); unsigned char h_r = ts_impl_h(node->right); return 1 + (h_l > h_r ? h_l : h_r); } static void ts_impl_rotate_right(struct treeset_node * *Z) { struct treeset_node *root = *Z; struct treeset_node *new_root = root->left; if (root->parent != ((void *)0)) { if (root->parent->left == root) root->parent->left = new_root; else root->parent->right = new_root; } new_root->parent = root->parent; root->parent = new_root; root->left = new_root->right; if (root->left) root->left->parent = root; new_root->right = root; root->height = ts_impl_hupdate(root); new_root->height = ts_impl_hupdate(new_root); *Z = new_root; } static void ts_impl_rotate_left(struct treeset_node * *Z) { struct treeset_node *root = *Z; struct treeset_node *new_root = root->right; if (root->parent != ((void *)0)) { if (root->parent->right == root) root->parent->right = new_root; else root->parent->left = new_root; } new_root->parent = root->parent; root->parent = new_root; root->right = new_root->left; if (root->right) root->right->parent = root; new_root->left = root; root->height = ts_impl_hupdate(root); new_root->height = ts_impl_hupdate(new_root); *Z = new_root; } static void ts_impl_rebalance(struct treeset * _set_, struct treeset_node * node) { struct treeset_node *scan = node, *child = ((void *)0); int balance; _Bool is_root = 0; while (scan != ((void *)0)) { if (scan->parent == ((void *)0)) is_root = 1; scan->height = ts_impl_hupdate(scan); balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); if (balance >= 2) { child = scan->right; if (ts_impl_h(child->right) < ts_impl_h(child->left)) ts_impl_rotate_right(&(scan->right)); ts_impl_rotate_left(&scan); } else if (balance <= -2) { child = scan->left; if (ts_impl_h(child->left) < ts_impl_h(child->right)) ts_impl_rotate_left(&(scan->left)); ts_impl_rotate_right(&scan); } if (is_root) { _set_->root = scan; is_root = 0; } scan = scan->parent; } } struct treeset_iter ts_iter_start(struct treeset * target) { struct treeset_iter iter; iter.target = target; iter.cursor = target->root; iter.first = ((void *)0); iter.last = ((void *)0); iter.index = 0; iter.start = 1; iter.end = ts_empty(target); if (!ts_empty(target)) { while (iter.cursor->left != ((void *)0)) iter.cursor = iter.cursor->left; iter.first = iter.cursor; iter.last = target->root; while (iter.last->right != ((void *)0)) iter.last = iter.last->right; } return iter; } struct treeset_iter ts_iter_end(struct treeset * target) { struct treeset_iter iter; iter.target = target; iter.cursor = target->root; iter.first = ((void *)0); iter.last = ((void *)0); iter.index = 0; iter.start = ts_empty(target); iter.end = 1; if (!ts_empty(target)) { while (iter.cursor->right != ((void *)0)) iter.cursor = iter.cursor->right; iter.last = iter.cursor; iter.first = target->root; while (iter.first->left != ((void *)0)) iter.first = iter.first->left; iter.index = target->count - 1; } return iter; } _Bool ts_iter_at_start(struct treeset_iter * iter) { return ts_empty(iter->target) || iter->start; } _Bool ts_iter_at_end(struct treeset_iter * iter) { return ts_empty(iter->target) || iter->end; } _Bool ts_iter_to_start(struct treeset_iter * iter) { if (!ts_empty(iter->target)) { iter->index = 0; iter->start = 1; iter->end = ts_empty(iter->target); iter->cursor = iter->first; return 1; } return 0; } _Bool ts_iter_to_end(struct treeset_iter * iter) { if (!ts_empty(iter->target)) { iter->index = iter->target->count - 1; iter->start = ts_empty(iter->target); iter->end = 1; iter->cursor = iter->last; return 1; } return 0; } _Bool ts_iter_next(struct treeset_iter * iter) { if (iter->end) return 0; if (iter->cursor == iter->last) { iter->end = 1; return 0; } iter->start = ts_empty(iter->target); if (iter->cursor->right != ((void *)0)) { iter->cursor = iter->cursor->right; while (iter->cursor->left != ((void *)0)) iter->cursor = iter->cursor->left; iter->index++; return 1; } while (1) { if (iter->cursor->parent->left == iter->cursor) { iter->cursor = iter->cursor->parent; iter->index++; return 1; } iter->cursor = iter->cursor->parent; } } _Bool ts_iter_prev(struct treeset_iter * iter) { if (iter->start) return 0; if (iter->cursor == iter->first) { iter->start = 1; return 0; } iter->end = ts_empty(iter->target); if (iter->cursor->left != ((void *)0)) { iter->cursor = iter->cursor->left; while (iter->cursor->right != ((void *)0)) iter->cursor = iter->cursor->right; iter->index--; return 1; } while (1) { if (iter->cursor->parent->right == iter->cursor) { iter->cursor = iter->cursor->parent; iter->index--; return 1; } iter->cursor = iter->cursor->parent; } } _Bool ts_iter_advance(struct treeset_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor == iter->last) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) ts_iter_next(iter); return 1; } _Bool ts_iter_rewind(struct treeset_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == iter->first) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) ts_iter_prev(iter); return 1; } _Bool ts_iter_go_to(struct treeset_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return ts_iter_rewind(iter, iter->index - index); else if (iter->index < index) return ts_iter_advance(iter, index - iter->index); return 1; } size_t ts_iter_value(struct treeset_iter * iter) { if (ts_empty(iter->target)) return (size_t){ 0 }; return iter->cursor->value; } size_t ts_iter_index(struct treeset_iter * iter) { return iter->index; } struct treeset *ts_union(struct treeset * _set1_, struct treeset * _set2_) { struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); struct treeset_iter iter2 = ts_iter_start(_set2_); for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) { ts_insert(_set_r_, ts_iter_value(&iter1)); } for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) { ts_insert(_set_r_, ts_iter_value(&iter2)); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_intersection(struct treeset * _set1_, struct treeset * _set2_) { struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; struct treeset_iter iter = ts_iter_start(_set_A_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set_B_, value) != ((void *)0)) ts_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_difference(struct treeset * _set1_, struct treeset * _set2_) { struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set2_, value) == ((void *)0)) ts_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_symmetric_difference(struct treeset * _set1_, struct treeset * _set2_) { struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); struct treeset_iter iter2 = ts_iter_start(_set2_); for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) { size_t value = ts_iter_value(&iter1); if (ts_impl_get_node(_set2_, value) == ((void *)0)) ts_insert(_set_r_, value); } for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) { size_t value = ts_iter_value(&iter2); if (ts_impl_get_node(_set1_, value) == ((void *)0)) ts_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } _Bool ts_is_subset(struct treeset * _set1_, struct treeset * _set2_) { if (_set1_->count > _set2_->count) return 0; if (ts_empty(_set1_)) return 1; struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set2_, value) == ((void *)0)) return 0; } return 1; } _Bool ts_is_superset(struct treeset * _set1_, struct treeset * _set2_) { return ts_is_subset(_set2_, _set1_); } _Bool ts_is_proper_subset(struct treeset * _set1_, struct treeset * _set2_) { if (_set1_->count >= _set2_->count) return 0; if (ts_empty(_set1_)) { if (!ts_empty(_set2_)) return 1; else return 0; } struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set2_, value) == ((void *)0)) return 0; } return 1; } _Bool ts_is_proper_superset(struct treeset * _set1_, struct treeset * _set2_) { return ts_is_proper_subset(_set2_, _set1_); } _Bool ts_is_disjointset(struct treeset * _set1_, struct treeset * _set2_) { if (ts_empty(_set1_)) return 1; struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set2_, value) != ((void *)0)) return 0; } return 1; } _Bool ts_to_string(struct treeset * _set_, FILE * fptr) { struct treeset *s_ = _set_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "root:%p, " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); } _Bool ts_print(struct treeset * _set_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); struct treeset_node *root = _set_->root; _Bool left_done = 0; size_t i = 0; while (root) { if (!left_done) { while (root->left) root = root->left; } if (!_set_->f_val->str(fptr, root->value)) return 0; if (++i < _set_->count) fprintf(fptr, "%s", separator); left_done = 1; if (root->right) { left_done = 0; root = root->right; } else if (root->parent) { while (root->parent && root == root->parent->right) root = root->parent; if (!root->parent) break; root = root->parent; } else break; } fprintf(fptr, "%s", end); return 1; } + + \ No newline at end of file diff --git a/tests/unt/cmc/bitset.h b/tests/unt/unt_cmc_bitset.h similarity index 99% rename from tests/unt/cmc/bitset.h rename to tests/unt/unt_cmc_bitset.h index daf9757..f54fed2 100644 --- a/tests/unt/cmc/bitset.h +++ b/tests/unt/unt_cmc_bitset.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_ITSET_H #define CMC_TESTS_UNT_CMC_ITSET_H -#include "../utl.h" +#include "utl.h" -#include "cmc/bitset.h" +#include "tst_cmc_bitset.h" struct cmc_alloc_node *bs_alloc_node = &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; diff --git a/tests/unt/cmc/deque.h b/tests/unt/unt_cmc_deque.h similarity index 99% rename from tests/unt/cmc/deque.h rename to tests/unt/unt_cmc_deque.h index a072906..d391f41 100644 --- a/tests/unt/cmc/deque.h +++ b/tests/unt/unt_cmc_deque.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_EQUE_H #define CMC_TESTS_UNT_CMC_EQUE_H -#include "../utl.h" +#include "utl.h" -#include "cmc/deque.h" +#include "tst_cmc_deque.h" struct deque_fval *d_fval = &(struct deque_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/hashbidimap.h b/tests/unt/unt_cmc_hashbidimap.h similarity index 99% rename from tests/unt/cmc/hashbidimap.h rename to tests/unt/unt_cmc_hashbidimap.h index 9c6c411..ca0f550 100644 --- a/tests/unt/cmc/hashbidimap.h +++ b/tests/unt/unt_cmc_hashbidimap.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_ASHBIDIMAP_H #define CMC_TESTS_UNT_CMC_ASHBIDIMAP_H -#include "../utl.h" +#include "utl.h" -#include "cmc/hashbidimap.h" +#include "tst_cmc_hashbidimap.h" struct hashbidimap_fkey *hbm_fkey = &(struct hashbidimap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/hashmap.h b/tests/unt/unt_cmc_hashmap.h similarity index 99% rename from tests/unt/cmc/hashmap.h rename to tests/unt/unt_cmc_hashmap.h index c255fa8..fee31f2 100644 --- a/tests/unt/cmc/hashmap.h +++ b/tests/unt/unt_cmc_hashmap.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_ASHMAP_H #define CMC_TESTS_UNT_CMC_ASHMAP_H -#include "../utl.h" +#include "utl.h" -#include "cmc/hashmap.h" +#include "tst_cmc_hashmap.h" struct hashmap_fkey *hm_fkey = &(struct hashmap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/hashmultimap.h b/tests/unt/unt_cmc_hashmultimap.h similarity index 99% rename from tests/unt/cmc/hashmultimap.h rename to tests/unt/unt_cmc_hashmultimap.h index c901a48..879e833 100644 --- a/tests/unt/cmc/hashmultimap.h +++ b/tests/unt/unt_cmc_hashmultimap.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_ASHMULTIMAP_H #define CMC_TESTS_UNT_CMC_ASHMULTIMAP_H -#include "../utl.h" +#include "utl.h" -#include "cmc/hashmultimap.h" +#include "tst_cmc_hashmultimap.h" struct hashmultimap_fkey *hmm_fkey = &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/hashmultiset.h b/tests/unt/unt_cmc_hashmultiset.h similarity index 99% rename from tests/unt/cmc/hashmultiset.h rename to tests/unt/unt_cmc_hashmultiset.h index bb70897..54f3922 100644 --- a/tests/unt/cmc/hashmultiset.h +++ b/tests/unt/unt_cmc_hashmultiset.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_ASHMULTISET_H #define CMC_TESTS_UNT_CMC_ASHMULTISET_H -#include "../utl.h" +#include "utl.h" -#include "cmc/hashmultiset.h" +#include "tst_cmc_hashmultiset.h" struct hashmultiset_fval *hms_fval = &(struct hashmultiset_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/hashset.h b/tests/unt/unt_cmc_hashset.h similarity index 99% rename from tests/unt/cmc/hashset.h rename to tests/unt/unt_cmc_hashset.h index 38e2933..2607bf9 100644 --- a/tests/unt/cmc/hashset.h +++ b/tests/unt/unt_cmc_hashset.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_ASHSET_H #define CMC_TESTS_UNT_CMC_ASHSET_H -#include "../utl.h" +#include "utl.h" -#include "cmc/hashset.h" +#include "tst_cmc_hashset.h" struct hashset_fval *hs_fval = &(struct hashset_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/heap.h b/tests/unt/unt_cmc_heap.h similarity index 99% rename from tests/unt/cmc/heap.h rename to tests/unt/unt_cmc_heap.h index ca320ef..77bf4ed 100644 --- a/tests/unt/cmc/heap.h +++ b/tests/unt/unt_cmc_heap.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_EAP_H #define CMC_TESTS_UNT_CMC_EAP_H -#include "../utl.h" +#include "utl.h" -#include "cmc/heap.h" +#include "tst_cmc_heap.h" struct heap_fval *h_fval = &(struct heap_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/intervalheap.h b/tests/unt/unt_cmc_intervalheap.h similarity index 99% rename from tests/unt/cmc/intervalheap.h rename to tests/unt/unt_cmc_intervalheap.h index 6b28430..4863ca7 100644 --- a/tests/unt/cmc/intervalheap.h +++ b/tests/unt/unt_cmc_intervalheap.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_NTERVALHEAP_H #define CMC_TESTS_UNT_CMC_NTERVALHEAP_H -#include "../utl.h" +#include "utl.h" -#include "cmc/intervalheap.h" +#include "tst_cmc_intervalheap.h" struct intervalheap_fval *ih_fval = &(struct intervalheap_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/linkedlist.h b/tests/unt/unt_cmc_linkedlist.h similarity index 99% rename from tests/unt/cmc/linkedlist.h rename to tests/unt/unt_cmc_linkedlist.h index cb78499..074ee42 100644 --- a/tests/unt/cmc/linkedlist.h +++ b/tests/unt/unt_cmc_linkedlist.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_INKEDLIST_H #define CMC_TESTS_UNT_CMC_INKEDLIST_H -#include "../utl.h" +#include "utl.h" -#include "cmc/linkedlist.h" +#include "tst_cmc_linkedlist.h" struct linkedlist_fval *ll_fval = &(struct linkedlist_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/list.h b/tests/unt/unt_cmc_list.h similarity index 99% rename from tests/unt/cmc/list.h rename to tests/unt/unt_cmc_list.h index 8bda4ac..46cf216 100644 --- a/tests/unt/cmc/list.h +++ b/tests/unt/unt_cmc_list.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_LIST_H #define CMC_TESTS_UNT_CMC_LIST_H -#include "../utl.h" +#include "utl.h" -#include "cmc/list.h" +#include "tst_cmc_list.h" struct list_fval *l_fval = &(struct list_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/queue.h b/tests/unt/unt_cmc_queue.h similarity index 99% rename from tests/unt/cmc/queue.h rename to tests/unt/unt_cmc_queue.h index b9a67b3..77f5117 100644 --- a/tests/unt/cmc/queue.h +++ b/tests/unt/unt_cmc_queue.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_QUEUE_H #define CMC_TESTS_UNT_CMC_QUEUE_H -#include "../utl.h" +#include "utl.h" -#include "cmc/queue.h" +#include "tst_cmc_queue.h" struct queue_fval *q_fval = &(struct queue_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/sortedlist.h b/tests/unt/unt_cmc_sortedlist.h similarity index 99% rename from tests/unt/cmc/sortedlist.h rename to tests/unt/unt_cmc_sortedlist.h index edb1b8c..103e56b 100644 --- a/tests/unt/cmc/sortedlist.h +++ b/tests/unt/unt_cmc_sortedlist.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_SORTEDLIST_H #define CMC_TESTS_UNT_CMC_SORTEDLIST_H -#include "../utl.h" +#include "utl.h" -#include "cmc/sortedlist.h" +#include "tst_cmc_sortedlist.h" struct sortedlist_fval *sl_fval = &(struct sortedlist_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/stack.h b/tests/unt/unt_cmc_stack.h similarity index 99% rename from tests/unt/cmc/stack.h rename to tests/unt/unt_cmc_stack.h index 4efb1f4..6cabe92 100644 --- a/tests/unt/cmc/stack.h +++ b/tests/unt/unt_cmc_stack.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_STACK_H #define CMC_TESTS_UNT_CMC_STACK_H -#include "../utl.h" +#include "utl.h" -#include "cmc/stack.h" +#include "tst_cmc_stack.h" struct stack_fval *s_fval = &(struct stack_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/treemap.h b/tests/unt/unt_cmc_treemap.h similarity index 99% rename from tests/unt/cmc/treemap.h rename to tests/unt/unt_cmc_treemap.h index 90e2483..250133e 100644 --- a/tests/unt/cmc/treemap.h +++ b/tests/unt/unt_cmc_treemap.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_TREEMAP_H #define CMC_TESTS_UNT_CMC_TREEMAP_H -#include "../utl.h" +#include "utl.h" -#include "cmc/treemap.h" +#include "tst_cmc_treemap.h" struct treemap_fkey *tm_fkey = &(struct treemap_fkey){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/cmc/treeset.h b/tests/unt/unt_cmc_treeset.h similarity index 99% rename from tests/unt/cmc/treeset.h rename to tests/unt/unt_cmc_treeset.h index 46dddf6..afee067 100644 --- a/tests/unt/cmc/treeset.h +++ b/tests/unt/unt_cmc_treeset.h @@ -1,9 +1,9 @@ #ifndef CMC_TESTS_UNT_CMC_TREESET_H #define CMC_TESTS_UNT_CMC_TREESET_H -#include "../utl.h" +#include "utl.h" -#include "cmc/treeset.h" +#include "tst_cmc_treeset.h" struct treeset_fval *ts_fval = &(struct treeset_fval){ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp diff --git a/tests/unt/utl/foreach.h b/tests/unt/unt_utl_foreach.h similarity index 97% rename from tests/unt/utl/foreach.h rename to tests/unt/unt_utl_foreach.h index 2336f99..938ca13 100644 --- a/tests/unt/utl/foreach.h +++ b/tests/unt/unt_utl_foreach.h @@ -1,24 +1,24 @@ #ifndef CMC_TESTS_UNT_UTL_FOREACH_H #define CMC_TESTS_UNT_UTL_FOREACH_H -#include "../utl.h" +#include "utl.h" -#include "cmc/bitset.h" -#include "cmc/deque.h" -#include "cmc/hashbidimap.h" -#include "cmc/hashmap.h" -#include "cmc/hashmultimap.h" -#include "cmc/hashmultiset.h" -#include "cmc/hashset.h" -#include "cmc/heap.h" -#include "cmc/intervalheap.h" -#include "cmc/linkedlist.h" -#include "cmc/list.h" -#include "cmc/queue.h" -#include "cmc/sortedlist.h" -#include "cmc/stack.h" -#include "cmc/treemap.h" -#include "cmc/treeset.h" +#include "tst_cmc_bitset.h" +#include "tst_cmc_deque.h" +#include "tst_cmc_hashbidimap.h" +#include "tst_cmc_hashmap.h" +#include "tst_cmc_hashmultimap.h" +#include "tst_cmc_hashmultiset.h" +#include "tst_cmc_hashset.h" +#include "tst_cmc_heap.h" +#include "tst_cmc_intervalheap.h" +#include "tst_cmc_linkedlist.h" +#include "tst_cmc_list.h" +#include "tst_cmc_queue.h" +#include "tst_cmc_sortedlist.h" +#include "tst_cmc_stack.h" +#include "tst_cmc_treemap.h" +#include "tst_cmc_treeset.h" CMC_CREATE_UNIT(ForEach, true, { // CMC_CREATE_TEST(CMC, { diff --git a/tests/unt/utl.h b/tests/unt/utl.h index 9835ae9..6078ead 100644 --- a/tests/unt/utl.h +++ b/tests/unt/utl.h @@ -6,11 +6,11 @@ #include #include -#include "cor/hashtable.h" -#include "utl/assert.h" -#include "utl/foreach.h" -#include "utl/futils.h" -#include "utl/test.h" +#include "cor_hashtable.h" +#include "utl_assert.h" +#include "utl_foreach.h" +#include "utl_futils.h" +#include "utl_test.h" size_t numhash(size_t a) { From 5740815a49b418bc55c40e7711b2dcf574b7d3e9 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sat, 26 Sep 2020 13:43:02 -0300 Subject: [PATCH 12/20] Formatting changes from last commit --- tests/include/tst_cmc_bitset.h | 49 +- tests/include/tst_cmc_deque.h | 83 ++- tests/include/tst_cmc_hashbidimap.h | 106 ++- tests/include/tst_cmc_hashmap.h | 105 ++- tests/include/tst_cmc_hashmultimap.h | 107 ++- tests/include/tst_cmc_hashmultiset.h | 103 ++- tests/include/tst_cmc_hashset.h | 93 ++- tests/include/tst_cmc_heap.h | 73 +- tests/include/tst_cmc_intervalheap.h | 77 ++- tests/include/tst_cmc_linkedlist.h | 97 ++- tests/include/tst_cmc_list.h | 87 ++- tests/include/tst_cmc_queue.h | 76 ++- tests/include/tst_cmc_sortedlist.h | 77 ++- tests/include/tst_cmc_stack.h | 73 +- tests/include/tst_cmc_treemap.h | 97 ++- tests/include/tst_cmc_treeset.h | 89 ++- tests/src/tst_cmc_bitset.c | 297 +++++++- tests/src/tst_cmc_deque.c | 519 +++++++++++++- tests/src/tst_cmc_hashbidimap.c | 859 ++++++++++++++++++++++- tests/src/tst_cmc_hashmap.c | 791 +++++++++++++++++++++- tests/src/tst_cmc_hashmultimap.c | 934 ++++++++++++++++++++++++- tests/src/tst_cmc_hashmultiset.c | 975 ++++++++++++++++++++++++++- tests/src/tst_cmc_hashset.c | 776 ++++++++++++++++++++- tests/src/tst_cmc_heap.c | 427 +++++++++++- tests/src/tst_cmc_intervalheap.c | 689 ++++++++++++++++++- tests/src/tst_cmc_linkedlist.c | 686 ++++++++++++++++++- tests/src/tst_cmc_list.c | 646 +++++++++++++++++- tests/src/tst_cmc_queue.c | 434 +++++++++++- tests/src/tst_cmc_sortedlist.c | 515 +++++++++++++- tests/src/tst_cmc_stack.c | 370 +++++++++- tests/src/tst_cmc_treemap.c | 855 ++++++++++++++++++++++- tests/src/tst_cmc_treeset.c | 844 ++++++++++++++++++++++- 32 files changed, 11801 insertions(+), 208 deletions(-) diff --git a/tests/include/tst_cmc_bitset.h b/tests/include/tst_cmc_bitset.h index 9e1998c..0c693e0 100644 --- a/tests/include/tst_cmc_bitset.h +++ b/tests/include/tst_cmc_bitset.h @@ -1,11 +1,44 @@ - #ifndef CMC_CMC_BITSET_TEST_H - #define CMC_CMC_BITSET_TEST_H +#ifndef CMC_CMC_BITSET_TEST_H +#define CMC_CMC_BITSET_TEST_H - #include "macro_collections.h" - - struct bitset { cmc_bitset_word *buffer; size_t capacity; size_t count; int flag; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct bitset_iter { struct bitset *target; size_t cursor; _Bool start; _Bool end; }; struct bitset *bs_new(size_t n_bits); struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); struct bitset bs_init(size_t n_bits); struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void bs_free(struct bitset * _bitset_); void bs_release(struct bitset _bitset_); void bs_customize(struct bitset * _bitset_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool bs_set(struct bitset * _bitset_, size_t bit_index); _Bool bs_set_range(struct bitset * _bitset_, size_t from, size_t to); _Bool bs_clear(struct bitset * _bitset_, size_t bit_index); _Bool bs_clear_range(struct bitset * _bitset_, size_t from, size_t to); _Bool bs_flip(struct bitset * _bitset_, size_t bit_index); _Bool bs_flip_range(struct bitset * _bitset_, size_t from, size_t to); _Bool bs_put(struct bitset * _bitset_, size_t bit_index, _Bool state); _Bool bs_put_range(struct bitset * _bitset_, size_t from, size_t to, _Bool state); _Bool bs_set_all(struct bitset * _bitset_); _Bool bs_clear_all(struct bitset * _bitset_); _Bool bs_flip_all(struct bitset * _bitset_); _Bool bs_get(struct bitset * _bitset_, size_t bit_index); _Bool bs_resize(struct bitset * _bitset_, size_t n_bits); - +#include "macro_collections.h" - #endif /* CMC_CMC_BITSET_TEST_H */ - \ No newline at end of file +struct bitset +{ + cmc_bitset_word *buffer; + size_t capacity; + size_t count; + int flag; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct bitset_iter +{ + struct bitset *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct bitset *bs_new(size_t n_bits); +struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +struct bitset bs_init(size_t n_bits); +struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void bs_free(struct bitset *_bitset_); +void bs_release(struct bitset _bitset_); +void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool bs_set(struct bitset *_bitset_, size_t bit_index); +_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to); +_Bool bs_clear(struct bitset *_bitset_, size_t bit_index); +_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to); +_Bool bs_flip(struct bitset *_bitset_, size_t bit_index); +_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to); +_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state); +_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state); +_Bool bs_set_all(struct bitset *_bitset_); +_Bool bs_clear_all(struct bitset *_bitset_); +_Bool bs_flip_all(struct bitset *_bitset_); +_Bool bs_get(struct bitset *_bitset_, size_t bit_index); +_Bool bs_resize(struct bitset *_bitset_, size_t n_bits); + +#endif /* CMC_CMC_BITSET_TEST_H */ diff --git a/tests/include/tst_cmc_deque.h b/tests/include/tst_cmc_deque.h index 70e222f..b664e2a 100644 --- a/tests/include/tst_cmc_deque.h +++ b/tests/include/tst_cmc_deque.h @@ -1,11 +1,78 @@ - #ifndef CMC_CMC_DEQUE_TEST_H - #define CMC_CMC_DEQUE_TEST_H +#ifndef CMC_CMC_DEQUE_TEST_H +#define CMC_CMC_DEQUE_TEST_H - #include "macro_collections.h" - - struct deque { size_t *buffer; size_t capacity; size_t count; size_t front; size_t back; int flag; struct deque_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct deque_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct deque *d_new(size_t capacity, struct deque_fval * f_val); struct deque *d_new_custom(size_t capacity, struct deque_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void d_clear(struct deque * _deque_); void d_free(struct deque * _deque_); void d_customize(struct deque * _deque_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool d_push_front(struct deque * _deque_, size_t value); _Bool d_push_back(struct deque * _deque_, size_t value); _Bool d_pop_front(struct deque * _deque_); _Bool d_pop_back(struct deque * _deque_); size_t d_front(struct deque * _deque_); size_t d_back(struct deque * _deque_); _Bool d_contains(struct deque * _deque_, size_t value); _Bool d_empty(struct deque * _deque_); _Bool d_full(struct deque * _deque_); size_t d_count(struct deque * _deque_); size_t d_capacity(struct deque * _deque_); int d_flag(struct deque * _deque_); _Bool d_resize(struct deque * _deque_, size_t capacity); struct deque *d_copy_of(struct deque * _deque_); _Bool d_equals(struct deque * _deque1_, struct deque * _deque2_); struct deque d_init(size_t capacity, struct deque_fval * f_val); struct deque d_init_custom(size_t capacity, struct deque_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void d_release(struct deque _deque_); struct deque_iter { struct deque *target; size_t cursor; size_t index; _Bool start; _Bool end; }; struct deque_iter d_iter_start(struct deque * target); struct deque_iter d_iter_end(struct deque * target); _Bool d_iter_at_start(struct deque_iter * iter); _Bool d_iter_at_end(struct deque_iter * iter); _Bool d_iter_to_start(struct deque_iter * iter); _Bool d_iter_to_end(struct deque_iter * iter); _Bool d_iter_next(struct deque_iter * iter); _Bool d_iter_prev(struct deque_iter * iter); _Bool d_iter_advance(struct deque_iter * iter, size_t steps); _Bool d_iter_rewind(struct deque_iter * iter, size_t steps); _Bool d_iter_go_to(struct deque_iter * iter, size_t index); size_t d_iter_value(struct deque_iter * iter); size_t *d_iter_rvalue(struct deque_iter * iter); size_t d_iter_index(struct deque_iter * iter); _Bool d_to_string(struct deque * _deque_, FILE * fptr); _Bool d_print(struct deque * _deque_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_DEQUE_TEST_H */ - \ No newline at end of file +struct deque +{ + size_t *buffer; + size_t capacity; + size_t count; + size_t front; + size_t back; + int flag; + struct deque_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct deque_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct deque *d_new(size_t capacity, struct deque_fval *f_val); +struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void d_clear(struct deque *_deque_); +void d_free(struct deque *_deque_); +void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool d_push_front(struct deque *_deque_, size_t value); +_Bool d_push_back(struct deque *_deque_, size_t value); +_Bool d_pop_front(struct deque *_deque_); +_Bool d_pop_back(struct deque *_deque_); +size_t d_front(struct deque *_deque_); +size_t d_back(struct deque *_deque_); +_Bool d_contains(struct deque *_deque_, size_t value); +_Bool d_empty(struct deque *_deque_); +_Bool d_full(struct deque *_deque_); +size_t d_count(struct deque *_deque_); +size_t d_capacity(struct deque *_deque_); +int d_flag(struct deque *_deque_); +_Bool d_resize(struct deque *_deque_, size_t capacity); +struct deque *d_copy_of(struct deque *_deque_); +_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_); +struct deque d_init(size_t capacity, struct deque_fval *f_val); +struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void d_release(struct deque _deque_); +struct deque_iter +{ + struct deque *target; + size_t cursor; + size_t index; + _Bool start; + _Bool end; +}; +struct deque_iter d_iter_start(struct deque *target); +struct deque_iter d_iter_end(struct deque *target); +_Bool d_iter_at_start(struct deque_iter *iter); +_Bool d_iter_at_end(struct deque_iter *iter); +_Bool d_iter_to_start(struct deque_iter *iter); +_Bool d_iter_to_end(struct deque_iter *iter); +_Bool d_iter_next(struct deque_iter *iter); +_Bool d_iter_prev(struct deque_iter *iter); +_Bool d_iter_advance(struct deque_iter *iter, size_t steps); +_Bool d_iter_rewind(struct deque_iter *iter, size_t steps); +_Bool d_iter_go_to(struct deque_iter *iter, size_t index); +size_t d_iter_value(struct deque_iter *iter); +size_t *d_iter_rvalue(struct deque_iter *iter); +size_t d_iter_index(struct deque_iter *iter); +_Bool d_to_string(struct deque *_deque_, FILE *fptr); +_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_DEQUE_TEST_H */ diff --git a/tests/include/tst_cmc_hashbidimap.h b/tests/include/tst_cmc_hashbidimap.h index a9a6387..c574437 100644 --- a/tests/include/tst_cmc_hashbidimap.h +++ b/tests/include/tst_cmc_hashbidimap.h @@ -1,11 +1,101 @@ - #ifndef CMC_CMC_HASHBIDIMAP_TEST_H - #define CMC_CMC_HASHBIDIMAP_TEST_H +#ifndef CMC_CMC_HASHBIDIMAP_TEST_H +#define CMC_CMC_HASHBIDIMAP_TEST_H - #include "macro_collections.h" - - struct hashbidimap { struct hashbidimap_entry * (*buffer)[2]; size_t capacity; size_t count; double load; int flag; struct hashbidimap_fkey * f_key; struct hashbidimap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; struct hashbidimap_iter (*it_start)(struct hashbidimap *); struct hashbidimap_iter (*it_end)(struct hashbidimap *); }; struct hashbidimap_entry { size_t key; size_t value; size_t dist[2]; struct hashbidimap_entry * *ref[2]; }; struct hashbidimap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashbidimap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashbidimap_iter { struct hashbidimap *target; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey * f_key, struct hashbidimap_fval * f_val); struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey * f_key, struct hashbidimap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hbm_clear(struct hashbidimap * _map_); void hbm_free(struct hashbidimap * _map_); void hbm_customize(struct hashbidimap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hbm_insert(struct hashbidimap * _map_, size_t key, size_t value); _Bool hbm_update_key(struct hashbidimap * _map_, size_t val, size_t new_key); _Bool hbm_update_val(struct hashbidimap * _map_, size_t key, size_t new_val); _Bool hbm_remove_by_key(struct hashbidimap * _map_, size_t key, size_t * out_key, size_t * out_val); _Bool hbm_remove_by_val(struct hashbidimap * _map_, size_t val, size_t * out_key, size_t * out_val); size_t hbm_get_key(struct hashbidimap * _map_, size_t val); size_t hbm_get_val(struct hashbidimap * _map_, size_t key); _Bool hbm_contains_key(struct hashbidimap * _map_, size_t key); _Bool hbm_contains_val(struct hashbidimap * _map_, size_t val); _Bool hbm_empty(struct hashbidimap * _map_); _Bool hbm_full(struct hashbidimap * _map_); size_t hbm_count(struct hashbidimap * _map_); size_t hbm_capacity(struct hashbidimap * _map_); double hbm_load(struct hashbidimap * _map_); int hbm_flag(struct hashbidimap * _map_); _Bool hbm_resize(struct hashbidimap * _map_, size_t capacity); struct hashbidimap *hbm_copy_of(struct hashbidimap * _map_); _Bool hbm_equals(struct hashbidimap * _map1_, struct hashbidimap * _map2_); struct hashbidimap_iter * hbm_iter_new(struct hashbidimap * target); void hbm_iter_free(struct hashbidimap_iter * iter); void hbm_iter_init(struct hashbidimap_iter * iter, struct hashbidimap * target); _Bool hbm_iter_start(struct hashbidimap_iter * iter); _Bool hbm_iter_end(struct hashbidimap_iter * iter); void hbm_iter_to_start(struct hashbidimap_iter * iter); void hbm_iter_to_end(struct hashbidimap_iter * iter); _Bool hbm_iter_next(struct hashbidimap_iter * iter); _Bool hbm_iter_prev(struct hashbidimap_iter * iter); _Bool hbm_iter_advance(struct hashbidimap_iter * iter, size_t steps); _Bool hbm_iter_rewind(struct hashbidimap_iter * iter, size_t steps); _Bool hbm_iter_go_to(struct hashbidimap_iter * iter, size_t index); size_t hbm_iter_key(struct hashbidimap_iter * iter); size_t hbm_iter_value(struct hashbidimap_iter * iter); size_t hbm_iter_index(struct hashbidimap_iter * iter); _Bool hbm_to_string(struct hashbidimap * _map_, FILE * fptr); _Bool hbm_print(struct hashbidimap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); - +#include "macro_collections.h" - #endif /* CMC_CMC_HASHBIDIMAP_TEST_H */ - \ No newline at end of file +struct hashbidimap +{ + struct hashbidimap_entry *(*buffer)[2]; + size_t capacity; + size_t count; + double load; + int flag; + struct hashbidimap_fkey *f_key; + struct hashbidimap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; + struct hashbidimap_iter (*it_start)(struct hashbidimap *); + struct hashbidimap_iter (*it_end)(struct hashbidimap *); +}; +struct hashbidimap_entry +{ + size_t key; + size_t value; + size_t dist[2]; + struct hashbidimap_entry **ref[2]; +}; +struct hashbidimap_fkey +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashbidimap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashbidimap_iter +{ + struct hashbidimap *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val); +struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void hbm_clear(struct hashbidimap *_map_); +void hbm_free(struct hashbidimap *_map_); +void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value); +_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key); +_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val); +_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val); +_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val); +size_t hbm_get_key(struct hashbidimap *_map_, size_t val); +size_t hbm_get_val(struct hashbidimap *_map_, size_t key); +_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key); +_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val); +_Bool hbm_empty(struct hashbidimap *_map_); +_Bool hbm_full(struct hashbidimap *_map_); +size_t hbm_count(struct hashbidimap *_map_); +size_t hbm_capacity(struct hashbidimap *_map_); +double hbm_load(struct hashbidimap *_map_); +int hbm_flag(struct hashbidimap *_map_); +_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity); +struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_); +_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_); +struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target); +void hbm_iter_free(struct hashbidimap_iter *iter); +void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target); +_Bool hbm_iter_start(struct hashbidimap_iter *iter); +_Bool hbm_iter_end(struct hashbidimap_iter *iter); +void hbm_iter_to_start(struct hashbidimap_iter *iter); +void hbm_iter_to_end(struct hashbidimap_iter *iter); +_Bool hbm_iter_next(struct hashbidimap_iter *iter); +_Bool hbm_iter_prev(struct hashbidimap_iter *iter); +_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps); +_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps); +_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); +size_t hbm_iter_key(struct hashbidimap_iter *iter); +size_t hbm_iter_value(struct hashbidimap_iter *iter); +size_t hbm_iter_index(struct hashbidimap_iter *iter); +_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr); +_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_HASHBIDIMAP_TEST_H */ diff --git a/tests/include/tst_cmc_hashmap.h b/tests/include/tst_cmc_hashmap.h index 490bae1..5bb61eb 100644 --- a/tests/include/tst_cmc_hashmap.h +++ b/tests/include/tst_cmc_hashmap.h @@ -1,11 +1,100 @@ - #ifndef CMC_CMC_HASHMAP_TEST_H - #define CMC_CMC_HASHMAP_TEST_H +#ifndef CMC_CMC_HASHMAP_TEST_H +#define CMC_CMC_HASHMAP_TEST_H - #include "macro_collections.h" - - struct hashmap { struct hashmap_entry * buffer; size_t capacity; size_t count; double load; int flag; struct hashmap_fkey * f_key; struct hashmap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct hashmap_entry { size_t key; size_t value; size_t dist; enum cmc_entry_state state; }; struct hashmap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val); struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hm_clear(struct hashmap * _map_); void hm_free(struct hashmap * _map_); void hm_customize(struct hashmap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hm_insert(struct hashmap * _map_, size_t key, size_t value); _Bool hm_update(struct hashmap * _map_, size_t key, size_t new_value, size_t * old_value); _Bool hm_remove(struct hashmap * _map_, size_t key, size_t * out_value); _Bool hm_max(struct hashmap * _map_, size_t * key, size_t * value); _Bool hm_min(struct hashmap * _map_, size_t * key, size_t * value); size_t hm_get(struct hashmap * _map_, size_t key); size_t *hm_get_ref(struct hashmap * _map_, size_t key); _Bool hm_contains(struct hashmap * _map_, size_t key); _Bool hm_empty(struct hashmap * _map_); _Bool hm_full(struct hashmap * _map_); size_t hm_count(struct hashmap * _map_); size_t hm_capacity(struct hashmap * _map_); double hm_load(struct hashmap * _map_); int hm_flag(struct hashmap * _map_); _Bool hm_resize(struct hashmap * _map_, size_t capacity); struct hashmap *hm_copy_of(struct hashmap * _map_); _Bool hm_equals(struct hashmap * _map1_, struct hashmap * _map2_); struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val); struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hm_release(struct hashmap _map_); struct hashmap_iter { struct hashmap *target; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashmap_iter hm_iter_start(struct hashmap * target); struct hashmap_iter hm_iter_end(struct hashmap * target); _Bool hm_iter_at_start(struct hashmap_iter * iter); _Bool hm_iter_at_end(struct hashmap_iter * iter); _Bool hm_iter_to_start(struct hashmap_iter * iter); _Bool hm_iter_to_end(struct hashmap_iter * iter); _Bool hm_iter_next(struct hashmap_iter * iter); _Bool hm_iter_prev(struct hashmap_iter * iter); _Bool hm_iter_advance(struct hashmap_iter * iter, size_t steps); _Bool hm_iter_rewind(struct hashmap_iter * iter, size_t steps); _Bool hm_iter_go_to(struct hashmap_iter * iter, size_t index); size_t hm_iter_key(struct hashmap_iter * iter); size_t hm_iter_value(struct hashmap_iter * iter); size_t *hm_iter_rvalue(struct hashmap_iter * iter); size_t hm_iter_index(struct hashmap_iter * iter); _Bool hm_to_string(struct hashmap * _map_, FILE * fptr); _Bool hm_print(struct hashmap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); - +#include "macro_collections.h" - #endif /* CMC_CMC_HASHMAP_TEST_H */ - \ No newline at end of file +struct hashmap +{ + struct hashmap_entry *buffer; + size_t capacity; + size_t count; + double load; + int flag; + struct hashmap_fkey *f_key; + struct hashmap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct hashmap_entry +{ + size_t key; + size_t value; + size_t dist; + enum cmc_entry_state state; +}; +struct hashmap_fkey +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); +struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void hm_clear(struct hashmap *_map_); +void hm_free(struct hashmap *_map_); +void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); +_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value); +_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value); +_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value); +_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value); +size_t hm_get(struct hashmap *_map_, size_t key); +size_t *hm_get_ref(struct hashmap *_map_, size_t key); +_Bool hm_contains(struct hashmap *_map_, size_t key); +_Bool hm_empty(struct hashmap *_map_); +_Bool hm_full(struct hashmap *_map_); +size_t hm_count(struct hashmap *_map_); +size_t hm_capacity(struct hashmap *_map_); +double hm_load(struct hashmap *_map_); +int hm_flag(struct hashmap *_map_); +_Bool hm_resize(struct hashmap *_map_, size_t capacity); +struct hashmap *hm_copy_of(struct hashmap *_map_); +_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_); +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); +struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void hm_release(struct hashmap _map_); +struct hashmap_iter +{ + struct hashmap *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashmap_iter hm_iter_start(struct hashmap *target); +struct hashmap_iter hm_iter_end(struct hashmap *target); +_Bool hm_iter_at_start(struct hashmap_iter *iter); +_Bool hm_iter_at_end(struct hashmap_iter *iter); +_Bool hm_iter_to_start(struct hashmap_iter *iter); +_Bool hm_iter_to_end(struct hashmap_iter *iter); +_Bool hm_iter_next(struct hashmap_iter *iter); +_Bool hm_iter_prev(struct hashmap_iter *iter); +_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps); +_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps); +_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index); +size_t hm_iter_key(struct hashmap_iter *iter); +size_t hm_iter_value(struct hashmap_iter *iter); +size_t *hm_iter_rvalue(struct hashmap_iter *iter); +size_t hm_iter_index(struct hashmap_iter *iter); +_Bool hm_to_string(struct hashmap *_map_, FILE *fptr); +_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_HASHMAP_TEST_H */ diff --git a/tests/include/tst_cmc_hashmultimap.h b/tests/include/tst_cmc_hashmultimap.h index 883ad18..7b44266 100644 --- a/tests/include/tst_cmc_hashmultimap.h +++ b/tests/include/tst_cmc_hashmultimap.h @@ -1,11 +1,102 @@ - #ifndef CMC_CMC_HASHMULTIMAP_TEST_H - #define CMC_CMC_HASHMULTIMAP_TEST_H +#ifndef CMC_CMC_HASHMULTIMAP_TEST_H +#define CMC_CMC_HASHMULTIMAP_TEST_H - #include "macro_collections.h" - - struct hashmultimap { struct hashmultimap_entry * (*buffer)[2]; size_t capacity; size_t count; double load; int flag; struct hashmultimap_fkey * f_key; struct hashmultimap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct hashmultimap_entry { size_t key; size_t value; struct hashmultimap_entry * next; struct hashmultimap_entry * prev; }; struct hashmultimap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmultimap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey * f_key, struct hashmultimap_fval * f_val); struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey * f_key, struct hashmultimap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hmm_clear(struct hashmultimap * _map_); void hmm_free(struct hashmultimap * _map_); void hmm_customize(struct hashmultimap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hmm_insert(struct hashmultimap * _map_, size_t key, size_t value); _Bool hmm_update(struct hashmultimap * _map_, size_t key, size_t new_value, size_t * old_value); size_t hmm_update_all(struct hashmultimap * _map_, size_t key, size_t new_value, size_t * *old_values); _Bool hmm_remove(struct hashmultimap * _map_, size_t key, size_t * out_value); size_t hmm_remove_all(struct hashmultimap * _map_, size_t key, size_t * *out_values); _Bool hmm_max(struct hashmultimap * _map_, size_t * key, size_t * value); _Bool hmm_min(struct hashmultimap * _map_, size_t * key, size_t * value); size_t hmm_get(struct hashmultimap * _map_, size_t key); size_t *hmm_get_ref(struct hashmultimap * _map_, size_t key); _Bool hmm_contains(struct hashmultimap * _map_, size_t key); _Bool hmm_empty(struct hashmultimap * _map_); _Bool hmm_full(struct hashmultimap * _map_); size_t hmm_count(struct hashmultimap * _map_); size_t hmm_key_count(struct hashmultimap * _map_, size_t key); size_t hmm_capacity(struct hashmultimap * _map_); double hmm_load(struct hashmultimap * _map_); int hmm_flag(struct hashmultimap * _map_); _Bool hmm_resize(struct hashmultimap * _map_, size_t capacity); struct hashmultimap *hmm_copy_of(struct hashmultimap * _map_); _Bool hmm_equals(struct hashmultimap * _map1_, struct hashmultimap * _map2_); struct hashmultimap_iter { struct hashmultimap *target; struct hashmultimap_entry * curr_entry; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashmultimap_iter hmm_iter_start(struct hashmultimap * target); struct hashmultimap_iter hmm_iter_end(struct hashmultimap * target); _Bool hmm_iter_at_start(struct hashmultimap_iter * iter); _Bool hmm_iter_at_end(struct hashmultimap_iter * iter); _Bool hmm_iter_to_start(struct hashmultimap_iter * iter); _Bool hmm_iter_to_end(struct hashmultimap_iter * iter); _Bool hmm_iter_next(struct hashmultimap_iter * iter); _Bool hmm_iter_prev(struct hashmultimap_iter * iter); _Bool hmm_iter_advance(struct hashmultimap_iter * iter, size_t steps); _Bool hmm_iter_rewind(struct hashmultimap_iter * iter, size_t steps); _Bool hmm_iter_go_to(struct hashmultimap_iter * iter, size_t index); size_t hmm_iter_key(struct hashmultimap_iter * iter); size_t hmm_iter_value(struct hashmultimap_iter * iter); size_t *hmm_iter_rvalue(struct hashmultimap_iter * iter); size_t hmm_iter_index(struct hashmultimap_iter * iter); _Bool hmm_to_string(struct hashmultimap * _map_, FILE * fptr); _Bool hmm_print(struct hashmultimap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); - +#include "macro_collections.h" - #endif /* CMC_CMC_HASHMULTIMAP_TEST_H */ - \ No newline at end of file +struct hashmultimap +{ + struct hashmultimap_entry *(*buffer)[2]; + size_t capacity; + size_t count; + double load; + int flag; + struct hashmultimap_fkey *f_key; + struct hashmultimap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct hashmultimap_entry +{ + size_t key; + size_t value; + struct hashmultimap_entry *next; + struct hashmultimap_entry *prev; +}; +struct hashmultimap_fkey +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmultimap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, + struct hashmultimap_fval *f_val); +struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, + struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void hmm_clear(struct hashmultimap *_map_); +void hmm_free(struct hashmultimap *_map_); +void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value); +_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value); +size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values); +_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value); +size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values); +_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value); +_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value); +size_t hmm_get(struct hashmultimap *_map_, size_t key); +size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key); +_Bool hmm_contains(struct hashmultimap *_map_, size_t key); +_Bool hmm_empty(struct hashmultimap *_map_); +_Bool hmm_full(struct hashmultimap *_map_); +size_t hmm_count(struct hashmultimap *_map_); +size_t hmm_key_count(struct hashmultimap *_map_, size_t key); +size_t hmm_capacity(struct hashmultimap *_map_); +double hmm_load(struct hashmultimap *_map_); +int hmm_flag(struct hashmultimap *_map_); +_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity); +struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_); +_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_); +struct hashmultimap_iter +{ + struct hashmultimap *target; + struct hashmultimap_entry *curr_entry; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target); +struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target); +_Bool hmm_iter_at_start(struct hashmultimap_iter *iter); +_Bool hmm_iter_at_end(struct hashmultimap_iter *iter); +_Bool hmm_iter_to_start(struct hashmultimap_iter *iter); +_Bool hmm_iter_to_end(struct hashmultimap_iter *iter); +_Bool hmm_iter_next(struct hashmultimap_iter *iter); +_Bool hmm_iter_prev(struct hashmultimap_iter *iter); +_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps); +_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps); +_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index); +size_t hmm_iter_key(struct hashmultimap_iter *iter); +size_t hmm_iter_value(struct hashmultimap_iter *iter); +size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter); +size_t hmm_iter_index(struct hashmultimap_iter *iter); +_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr); +_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_HASHMULTIMAP_TEST_H */ diff --git a/tests/include/tst_cmc_hashmultiset.h b/tests/include/tst_cmc_hashmultiset.h index 8fc3e80..6ab4627 100644 --- a/tests/include/tst_cmc_hashmultiset.h +++ b/tests/include/tst_cmc_hashmultiset.h @@ -1,11 +1,98 @@ - #ifndef CMC_CMC_HASHMULTISET_TEST_H - #define CMC_CMC_HASHMULTISET_TEST_H +#ifndef CMC_CMC_HASHMULTISET_TEST_H +#define CMC_CMC_HASHMULTISET_TEST_H - #include "macro_collections.h" - - struct hashmultiset { struct hashmultiset_entry * buffer; size_t capacity; size_t count; size_t cardinality; double load; int flag; struct hashmultiset_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct hashmultiset_entry { size_t value; size_t multiplicity; size_t dist; enum cmc_entry_state state; }; struct hashmultiset_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval * f_val); struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hms_clear(struct hashmultiset * _set_); void hms_free(struct hashmultiset * _set_); void hms_customize(struct hashmultiset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hms_insert(struct hashmultiset * _set_, size_t value); _Bool hms_insert_many(struct hashmultiset * _set_, size_t value, size_t count); _Bool hms_update(struct hashmultiset * _set_, size_t value, size_t multiplicity); _Bool hms_remove(struct hashmultiset * _set_, size_t value); size_t hms_remove_all(struct hashmultiset * _set_, size_t value); _Bool hms_max(struct hashmultiset * _set_, size_t * value); _Bool hms_min(struct hashmultiset * _set_, size_t * value); size_t hms_multiplicity_of(struct hashmultiset * _set_, size_t value); _Bool hms_contains(struct hashmultiset * _set_, size_t value); _Bool hms_empty(struct hashmultiset * _set_); _Bool hms_full(struct hashmultiset * _set_); size_t hms_count(struct hashmultiset * _set_); size_t hms_cardinality(struct hashmultiset * _set_); size_t hms_capacity(struct hashmultiset * _set_); double hms_load(struct hashmultiset * _set_); int hms_flag(struct hashmultiset * _set_); _Bool hms_resize(struct hashmultiset * _set_, size_t capacity); struct hashmultiset *hms_copy_of(struct hashmultiset * _set_); _Bool hms_equals(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset_iter { struct hashmultiset *target; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashmultiset_iter hms_iter_start(struct hashmultiset * target); struct hashmultiset_iter hms_iter_end(struct hashmultiset * target); _Bool hms_iter_at_start(struct hashmultiset_iter * iter); _Bool hms_iter_at_end(struct hashmultiset_iter * iter); _Bool hms_iter_to_start(struct hashmultiset_iter * iter); _Bool hms_iter_to_end(struct hashmultiset_iter * iter); _Bool hms_iter_next(struct hashmultiset_iter * iter); _Bool hms_iter_prev(struct hashmultiset_iter * iter); _Bool hms_iter_advance(struct hashmultiset_iter * iter, size_t steps); _Bool hms_iter_rewind(struct hashmultiset_iter * iter, size_t steps); _Bool hms_iter_go_to(struct hashmultiset_iter * iter, size_t index); size_t hms_iter_value(struct hashmultiset_iter * iter); size_t hms_iter_multiplicity(struct hashmultiset_iter * iter); size_t hms_iter_index(struct hashmultiset_iter * iter); struct hashmultiset *hms_union(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset *hms_intersection(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset *hms_difference(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset *hms_summation(struct hashmultiset * _set1_, struct hashmultiset * _set2_); struct hashmultiset *hms_symmetric_difference(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_subset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_superset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_proper_subset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_proper_superset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_is_disjointset(struct hashmultiset * _set1_, struct hashmultiset * _set2_); _Bool hms_to_string(struct hashmultiset * _set_, FILE * fptr); _Bool hms_print(struct hashmultiset * _set_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); - +#include "macro_collections.h" - #endif /* CMC_CMC_HASHMULTISET_TEST_H */ - \ No newline at end of file +struct hashmultiset +{ + struct hashmultiset_entry *buffer; + size_t capacity; + size_t count; + size_t cardinality; + double load; + int flag; + struct hashmultiset_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct hashmultiset_entry +{ + size_t value; + size_t multiplicity; + size_t dist; + enum cmc_entry_state state; +}; +struct hashmultiset_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val); +struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void hms_clear(struct hashmultiset *_set_); +void hms_free(struct hashmultiset *_set_); +void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hms_insert(struct hashmultiset *_set_, size_t value); +_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count); +_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity); +_Bool hms_remove(struct hashmultiset *_set_, size_t value); +size_t hms_remove_all(struct hashmultiset *_set_, size_t value); +_Bool hms_max(struct hashmultiset *_set_, size_t *value); +_Bool hms_min(struct hashmultiset *_set_, size_t *value); +size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value); +_Bool hms_contains(struct hashmultiset *_set_, size_t value); +_Bool hms_empty(struct hashmultiset *_set_); +_Bool hms_full(struct hashmultiset *_set_); +size_t hms_count(struct hashmultiset *_set_); +size_t hms_cardinality(struct hashmultiset *_set_); +size_t hms_capacity(struct hashmultiset *_set_); +double hms_load(struct hashmultiset *_set_); +int hms_flag(struct hashmultiset *_set_); +_Bool hms_resize(struct hashmultiset *_set_, size_t capacity); +struct hashmultiset *hms_copy_of(struct hashmultiset *_set_); +_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset_iter +{ + struct hashmultiset *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashmultiset_iter hms_iter_start(struct hashmultiset *target); +struct hashmultiset_iter hms_iter_end(struct hashmultiset *target); +_Bool hms_iter_at_start(struct hashmultiset_iter *iter); +_Bool hms_iter_at_end(struct hashmultiset_iter *iter); +_Bool hms_iter_to_start(struct hashmultiset_iter *iter); +_Bool hms_iter_to_end(struct hashmultiset_iter *iter); +_Bool hms_iter_next(struct hashmultiset_iter *iter); +_Bool hms_iter_prev(struct hashmultiset_iter *iter); +_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps); +_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps); +_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index); +size_t hms_iter_value(struct hashmultiset_iter *iter); +size_t hms_iter_multiplicity(struct hashmultiset_iter *iter); +size_t hms_iter_index(struct hashmultiset_iter *iter); +struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); +_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr); +_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_HASHMULTISET_TEST_H */ diff --git a/tests/include/tst_cmc_hashset.h b/tests/include/tst_cmc_hashset.h index bf1b031..a9ab75c 100644 --- a/tests/include/tst_cmc_hashset.h +++ b/tests/include/tst_cmc_hashset.h @@ -1,11 +1,88 @@ - #ifndef CMC_CMC_HASHSET_TEST_H - #define CMC_CMC_HASHSET_TEST_H +#ifndef CMC_CMC_HASHSET_TEST_H +#define CMC_CMC_HASHSET_TEST_H - #include "macro_collections.h" - - struct hashset { struct hashset_entry * buffer; size_t capacity; size_t count; double load; int flag; struct hashset_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct hashset_entry { size_t value; size_t dist; enum cmc_entry_state state; }; struct hashset_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct hashset *hs_new(size_t capacity, double load, struct hashset_fval * f_val); struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void hs_clear(struct hashset * _set_); void hs_free(struct hashset * _set_); void hs_customize(struct hashset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool hs_insert(struct hashset * _set_, size_t value); _Bool hs_remove(struct hashset * _set_, size_t value); _Bool hs_max(struct hashset * _set_, size_t * value); _Bool hs_min(struct hashset * _set_, size_t * value); _Bool hs_contains(struct hashset * _set_, size_t value); _Bool hs_empty(struct hashset * _set_); _Bool hs_full(struct hashset * _set_); size_t hs_count(struct hashset * _set_); size_t hs_capacity(struct hashset * _set_); double hs_load(struct hashset * _set_); int hs_flag(struct hashset * _set_); _Bool hs_resize(struct hashset * _set_, size_t capacity); struct hashset *hs_copy_of(struct hashset * _set_); _Bool hs_equals(struct hashset * _set1_, struct hashset * _set2_); struct hashset_iter { struct hashset *target; size_t cursor; size_t index; size_t first; size_t last; _Bool start; _Bool end; }; struct hashset_iter hs_iter_start(struct hashset * target); struct hashset_iter hs_iter_end(struct hashset * target); _Bool hs_iter_at_start(struct hashset_iter * iter); _Bool hs_iter_at_end(struct hashset_iter * iter); _Bool hs_iter_to_start(struct hashset_iter * iter); _Bool hs_iter_to_end(struct hashset_iter * iter); _Bool hs_iter_next(struct hashset_iter * iter); _Bool hs_iter_prev(struct hashset_iter * iter); _Bool hs_iter_advance(struct hashset_iter * iter, size_t steps); _Bool hs_iter_rewind(struct hashset_iter * iter, size_t steps); _Bool hs_iter_go_to(struct hashset_iter * iter, size_t index); size_t hs_iter_value(struct hashset_iter * iter); size_t hs_iter_index(struct hashset_iter * iter); struct hashset *hs_union(struct hashset * _set1_, struct hashset * _set2_); struct hashset *hs_intersection(struct hashset * _set1_, struct hashset * _set2_); struct hashset *hs_difference(struct hashset * _set1_, struct hashset * _set2_); struct hashset *hs_symmetric_difference(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_subset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_superset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_proper_subset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_proper_superset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_is_disjointset(struct hashset * _set1_, struct hashset * _set2_); _Bool hs_to_string(struct hashset * _set_, FILE * fptr); _Bool hs_print(struct hashset * _set_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_HASHSET_TEST_H */ - \ No newline at end of file +struct hashset +{ + struct hashset_entry *buffer; + size_t capacity; + size_t count; + double load; + int flag; + struct hashset_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct hashset_entry +{ + size_t value; + size_t dist; + enum cmc_entry_state state; +}; +struct hashset_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val); +struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void hs_clear(struct hashset *_set_); +void hs_free(struct hashset *_set_); +void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool hs_insert(struct hashset *_set_, size_t value); +_Bool hs_remove(struct hashset *_set_, size_t value); +_Bool hs_max(struct hashset *_set_, size_t *value); +_Bool hs_min(struct hashset *_set_, size_t *value); +_Bool hs_contains(struct hashset *_set_, size_t value); +_Bool hs_empty(struct hashset *_set_); +_Bool hs_full(struct hashset *_set_); +size_t hs_count(struct hashset *_set_); +size_t hs_capacity(struct hashset *_set_); +double hs_load(struct hashset *_set_); +int hs_flag(struct hashset *_set_); +_Bool hs_resize(struct hashset *_set_, size_t capacity); +struct hashset *hs_copy_of(struct hashset *_set_); +_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_); +struct hashset_iter +{ + struct hashset *target; + size_t cursor; + size_t index; + size_t first; + size_t last; + _Bool start; + _Bool end; +}; +struct hashset_iter hs_iter_start(struct hashset *target); +struct hashset_iter hs_iter_end(struct hashset *target); +_Bool hs_iter_at_start(struct hashset_iter *iter); +_Bool hs_iter_at_end(struct hashset_iter *iter); +_Bool hs_iter_to_start(struct hashset_iter *iter); +_Bool hs_iter_to_end(struct hashset_iter *iter); +_Bool hs_iter_next(struct hashset_iter *iter); +_Bool hs_iter_prev(struct hashset_iter *iter); +_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps); +_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps); +_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index); +size_t hs_iter_value(struct hashset_iter *iter); +size_t hs_iter_index(struct hashset_iter *iter); +struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); +_Bool hs_to_string(struct hashset *_set_, FILE *fptr); +_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_HASHSET_TEST_H */ diff --git a/tests/include/tst_cmc_heap.h b/tests/include/tst_cmc_heap.h index 73aa0c6..8b062f1 100644 --- a/tests/include/tst_cmc_heap.h +++ b/tests/include/tst_cmc_heap.h @@ -1,11 +1,68 @@ - #ifndef CMC_CMC_HEAP_TEST_H - #define CMC_CMC_HEAP_TEST_H +#ifndef CMC_CMC_HEAP_TEST_H +#define CMC_CMC_HEAP_TEST_H - #include "macro_collections.h" - - struct heap { size_t *buffer; size_t capacity; size_t count; enum cmc_heap_order HO; int flag; struct heap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct heap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval * f_val); struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void h_clear(struct heap * _heap_); void h_free(struct heap * _heap_); void h_customize(struct heap * _heap_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool h_insert(struct heap * _heap_, size_t value); _Bool h_remove(struct heap * _heap_); size_t h_peek(struct heap * _heap_); _Bool h_contains(struct heap * _heap_, size_t value); _Bool h_empty(struct heap * _heap_); _Bool h_full(struct heap * _heap_); size_t h_count(struct heap * _heap_); size_t h_capacity(struct heap * _heap_); int h_flag(struct heap * _heap_); _Bool h_resize(struct heap * _heap_, size_t capacity); struct heap *h_copy_of(struct heap * _heap_); _Bool h_equals(struct heap * _heap1_, struct heap * _heap2_); struct heap_iter { struct heap *target; size_t cursor; _Bool start; _Bool end; }; struct heap_iter h_iter_start(struct heap * target); struct heap_iter h_iter_end(struct heap * target); _Bool h_iter_at_start(struct heap_iter * iter); _Bool h_iter_at_end(struct heap_iter * iter); _Bool h_iter_to_start(struct heap_iter * iter); _Bool h_iter_to_end(struct heap_iter * iter); _Bool h_iter_next(struct heap_iter * iter); _Bool h_iter_prev(struct heap_iter * iter); _Bool h_iter_advance(struct heap_iter * iter, size_t steps); _Bool h_iter_rewind(struct heap_iter * iter, size_t steps); _Bool h_iter_go_to(struct heap_iter * iter, size_t index); size_t h_iter_value(struct heap_iter * iter); size_t h_iter_index(struct heap_iter * iter); _Bool h_to_string(struct heap * _heap_, FILE * fptr); _Bool h_print(struct heap * _heap_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_HEAP_TEST_H */ - \ No newline at end of file +struct heap +{ + size_t *buffer; + size_t capacity; + size_t count; + enum cmc_heap_order HO; + int flag; + struct heap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct heap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val); +struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +void h_clear(struct heap *_heap_); +void h_free(struct heap *_heap_); +void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool h_insert(struct heap *_heap_, size_t value); +_Bool h_remove(struct heap *_heap_); +size_t h_peek(struct heap *_heap_); +_Bool h_contains(struct heap *_heap_, size_t value); +_Bool h_empty(struct heap *_heap_); +_Bool h_full(struct heap *_heap_); +size_t h_count(struct heap *_heap_); +size_t h_capacity(struct heap *_heap_); +int h_flag(struct heap *_heap_); +_Bool h_resize(struct heap *_heap_, size_t capacity); +struct heap *h_copy_of(struct heap *_heap_); +_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_); +struct heap_iter +{ + struct heap *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct heap_iter h_iter_start(struct heap *target); +struct heap_iter h_iter_end(struct heap *target); +_Bool h_iter_at_start(struct heap_iter *iter); +_Bool h_iter_at_end(struct heap_iter *iter); +_Bool h_iter_to_start(struct heap_iter *iter); +_Bool h_iter_to_end(struct heap_iter *iter); +_Bool h_iter_next(struct heap_iter *iter); +_Bool h_iter_prev(struct heap_iter *iter); +_Bool h_iter_advance(struct heap_iter *iter, size_t steps); +_Bool h_iter_rewind(struct heap_iter *iter, size_t steps); +_Bool h_iter_go_to(struct heap_iter *iter, size_t index); +size_t h_iter_value(struct heap_iter *iter); +size_t h_iter_index(struct heap_iter *iter); +_Bool h_to_string(struct heap *_heap_, FILE *fptr); +_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_HEAP_TEST_H */ diff --git a/tests/include/tst_cmc_intervalheap.h b/tests/include/tst_cmc_intervalheap.h index 28b3010..5bc4fb2 100644 --- a/tests/include/tst_cmc_intervalheap.h +++ b/tests/include/tst_cmc_intervalheap.h @@ -1,11 +1,72 @@ - #ifndef CMC_CMC_INTERVALHEAP_TEST_H - #define CMC_CMC_INTERVALHEAP_TEST_H +#ifndef CMC_CMC_INTERVALHEAP_TEST_H +#define CMC_CMC_INTERVALHEAP_TEST_H - #include "macro_collections.h" - - struct intervalheap { size_t (*buffer)[2]; size_t capacity; size_t size; size_t count; int flag; struct intervalheap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct intervalheap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval * f_val); struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void ih_clear(struct intervalheap * _heap_); void ih_free(struct intervalheap * _heap_); void ih_customize(struct intervalheap * _heap_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool ih_insert(struct intervalheap * _heap_, size_t value); _Bool ih_remove_max(struct intervalheap * _heap_); _Bool ih_remove_min(struct intervalheap * _heap_); _Bool ih_update_max(struct intervalheap * _heap_, size_t value); _Bool ih_update_min(struct intervalheap * _heap_, size_t value); size_t ih_max(struct intervalheap * _heap_); size_t ih_min(struct intervalheap * _heap_); _Bool ih_contains(struct intervalheap * _heap_, size_t value); _Bool ih_empty(struct intervalheap * _heap_); _Bool ih_full(struct intervalheap * _heap_); size_t ih_count(struct intervalheap * _heap_); size_t ih_capacity(struct intervalheap * _heap_); int ih_flag(struct intervalheap * _heap_); _Bool ih_resize(struct intervalheap * _heap_, size_t capacity); struct intervalheap *ih_copy_of(struct intervalheap * _heap_); _Bool ih_equals(struct intervalheap * _heap1_, struct intervalheap * _heap2_); struct intervalheap_iter { struct intervalheap *target; size_t cursor; _Bool start; _Bool end; }; struct intervalheap_iter ih_iter_start(struct intervalheap * target); struct intervalheap_iter ih_iter_end(struct intervalheap * target); _Bool ih_iter_at_start(struct intervalheap_iter * iter); _Bool ih_iter_at_end(struct intervalheap_iter * iter); _Bool ih_iter_to_start(struct intervalheap_iter * iter); _Bool ih_iter_to_end(struct intervalheap_iter * iter); _Bool ih_iter_next(struct intervalheap_iter * iter); _Bool ih_iter_prev(struct intervalheap_iter * iter); _Bool ih_iter_advance(struct intervalheap_iter * iter, size_t steps); _Bool ih_iter_rewind(struct intervalheap_iter * iter, size_t steps); _Bool ih_iter_go_to(struct intervalheap_iter * iter, size_t index); size_t ih_iter_value(struct intervalheap_iter * iter); size_t ih_iter_index(struct intervalheap_iter * iter); _Bool ih_to_string(struct intervalheap * _heap_, FILE * fptr); _Bool ih_print(struct intervalheap * _heap_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_INTERVALHEAP_TEST_H */ - \ No newline at end of file +struct intervalheap +{ + size_t (*buffer)[2]; + size_t capacity; + size_t size; + size_t count; + int flag; + struct intervalheap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct intervalheap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val); +struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void ih_clear(struct intervalheap *_heap_); +void ih_free(struct intervalheap *_heap_); +void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool ih_insert(struct intervalheap *_heap_, size_t value); +_Bool ih_remove_max(struct intervalheap *_heap_); +_Bool ih_remove_min(struct intervalheap *_heap_); +_Bool ih_update_max(struct intervalheap *_heap_, size_t value); +_Bool ih_update_min(struct intervalheap *_heap_, size_t value); +size_t ih_max(struct intervalheap *_heap_); +size_t ih_min(struct intervalheap *_heap_); +_Bool ih_contains(struct intervalheap *_heap_, size_t value); +_Bool ih_empty(struct intervalheap *_heap_); +_Bool ih_full(struct intervalheap *_heap_); +size_t ih_count(struct intervalheap *_heap_); +size_t ih_capacity(struct intervalheap *_heap_); +int ih_flag(struct intervalheap *_heap_); +_Bool ih_resize(struct intervalheap *_heap_, size_t capacity); +struct intervalheap *ih_copy_of(struct intervalheap *_heap_); +_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_); +struct intervalheap_iter +{ + struct intervalheap *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct intervalheap_iter ih_iter_start(struct intervalheap *target); +struct intervalheap_iter ih_iter_end(struct intervalheap *target); +_Bool ih_iter_at_start(struct intervalheap_iter *iter); +_Bool ih_iter_at_end(struct intervalheap_iter *iter); +_Bool ih_iter_to_start(struct intervalheap_iter *iter); +_Bool ih_iter_to_end(struct intervalheap_iter *iter); +_Bool ih_iter_next(struct intervalheap_iter *iter); +_Bool ih_iter_prev(struct intervalheap_iter *iter); +_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps); +_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps); +_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index); +size_t ih_iter_value(struct intervalheap_iter *iter); +size_t ih_iter_index(struct intervalheap_iter *iter); +_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr); +_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_INTERVALHEAP_TEST_H */ diff --git a/tests/include/tst_cmc_linkedlist.h b/tests/include/tst_cmc_linkedlist.h index e682e9e..c06925d 100644 --- a/tests/include/tst_cmc_linkedlist.h +++ b/tests/include/tst_cmc_linkedlist.h @@ -1,11 +1,92 @@ - #ifndef CMC_CMC_LINKEDLIST_TEST_H - #define CMC_CMC_LINKEDLIST_TEST_H +#ifndef CMC_CMC_LINKEDLIST_TEST_H +#define CMC_CMC_LINKEDLIST_TEST_H - #include "macro_collections.h" - - struct linkedlist { struct linkedlist_node * head; struct linkedlist_node * tail; size_t count; int flag; struct linkedlist_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct linkedlist_node { size_t value; struct linkedlist_node * next; struct linkedlist_node * prev; }; struct linkedlist_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct linkedlist *ll_new(struct linkedlist_fval * f_val); struct linkedlist *ll_new_custom(struct linkedlist_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void ll_clear(struct linkedlist * _list_); void ll_free(struct linkedlist * _list_); void ll_customize(struct linkedlist * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool ll_push_front(struct linkedlist * _list_, size_t value); _Bool ll_push_at(struct linkedlist * _list_, size_t value, size_t index); _Bool ll_push_back(struct linkedlist * _list_, size_t value); _Bool ll_pop_front(struct linkedlist * _list_); _Bool ll_pop_at(struct linkedlist * _list_, size_t index); _Bool ll_pop_back(struct linkedlist * _list_); size_t ll_front(struct linkedlist * _list_); size_t ll_get(struct linkedlist * _list_, size_t index); size_t *ll_get_ref(struct linkedlist * _list_, size_t index); size_t ll_back(struct linkedlist * _list_); _Bool ll_contains(struct linkedlist * _list_, size_t value); _Bool ll_empty(struct linkedlist * _list_); size_t ll_count(struct linkedlist * _list_); int ll_flag(struct linkedlist * _list_); struct linkedlist *ll_copy_of(struct linkedlist * _list_); _Bool ll_equals(struct linkedlist * _list1_, struct linkedlist * _list2_); struct linkedlist_iter { struct linkedlist *target; struct linkedlist_node * cursor; size_t index; _Bool start; _Bool end; }; struct linkedlist_iter ll_iter_start(struct linkedlist * target); struct linkedlist_iter ll_iter_end(struct linkedlist * target); _Bool ll_iter_at_start(struct linkedlist_iter * iter); _Bool ll_iter_at_end(struct linkedlist_iter * iter); _Bool ll_iter_to_start(struct linkedlist_iter * iter); _Bool ll_iter_to_end(struct linkedlist_iter * iter); _Bool ll_iter_next(struct linkedlist_iter * iter); _Bool ll_iter_prev(struct linkedlist_iter * iter); _Bool ll_iter_advance(struct linkedlist_iter * iter, size_t steps); _Bool ll_iter_rewind(struct linkedlist_iter * iter, size_t steps); _Bool ll_iter_go_to(struct linkedlist_iter * iter, size_t index); size_t ll_iter_value(struct linkedlist_iter * iter); size_t *ll_iter_rvalue(struct linkedlist_iter * iter); size_t ll_iter_index(struct linkedlist_iter * iter); struct linkedlist_node * ll_iter_node(struct linkedlist_iter * iter); struct linkedlist_node * ll_new_node(struct linkedlist * _list_, size_t value); void ll_free_node(struct linkedlist * _list_, struct linkedlist_node * _node_); struct linkedlist_node * ll_head(struct linkedlist * _list_); struct linkedlist_node * ll_get_node(struct linkedlist * _list_, size_t index); struct linkedlist_node * ll_tail(struct linkedlist * _list_); _Bool ll_add_next(struct linkedlist * _owner_, struct linkedlist_node * _node_, size_t value); _Bool ll_add_prev(struct linkedlist * _owner_, struct linkedlist_node * _node_, size_t value); _Bool ll_del_next(struct linkedlist * _owner_, struct linkedlist_node * _node_); _Bool ll_del_curr(struct linkedlist * _owner_, struct linkedlist_node * _node_); _Bool ll_del_prev(struct linkedlist * _owner_, struct linkedlist_node * _node_); struct linkedlist_node * ll_next_node(struct linkedlist_node * _node_); struct linkedlist_node * ll_prev_node(struct linkedlist_node * _node_); _Bool ll_to_string(struct linkedlist * _list_, FILE * fptr); _Bool ll_print(struct linkedlist * _list_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_LINKEDLIST_TEST_H */ - \ No newline at end of file +struct linkedlist +{ + struct linkedlist_node *head; + struct linkedlist_node *tail; + size_t count; + int flag; + struct linkedlist_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct linkedlist_node +{ + size_t value; + struct linkedlist_node *next; + struct linkedlist_node *prev; +}; +struct linkedlist_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct linkedlist *ll_new(struct linkedlist_fval *f_val); +struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void ll_clear(struct linkedlist *_list_); +void ll_free(struct linkedlist *_list_); +void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool ll_push_front(struct linkedlist *_list_, size_t value); +_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index); +_Bool ll_push_back(struct linkedlist *_list_, size_t value); +_Bool ll_pop_front(struct linkedlist *_list_); +_Bool ll_pop_at(struct linkedlist *_list_, size_t index); +_Bool ll_pop_back(struct linkedlist *_list_); +size_t ll_front(struct linkedlist *_list_); +size_t ll_get(struct linkedlist *_list_, size_t index); +size_t *ll_get_ref(struct linkedlist *_list_, size_t index); +size_t ll_back(struct linkedlist *_list_); +_Bool ll_contains(struct linkedlist *_list_, size_t value); +_Bool ll_empty(struct linkedlist *_list_); +size_t ll_count(struct linkedlist *_list_); +int ll_flag(struct linkedlist *_list_); +struct linkedlist *ll_copy_of(struct linkedlist *_list_); +_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_); +struct linkedlist_iter +{ + struct linkedlist *target; + struct linkedlist_node *cursor; + size_t index; + _Bool start; + _Bool end; +}; +struct linkedlist_iter ll_iter_start(struct linkedlist *target); +struct linkedlist_iter ll_iter_end(struct linkedlist *target); +_Bool ll_iter_at_start(struct linkedlist_iter *iter); +_Bool ll_iter_at_end(struct linkedlist_iter *iter); +_Bool ll_iter_to_start(struct linkedlist_iter *iter); +_Bool ll_iter_to_end(struct linkedlist_iter *iter); +_Bool ll_iter_next(struct linkedlist_iter *iter); +_Bool ll_iter_prev(struct linkedlist_iter *iter); +_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps); +_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps); +_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index); +size_t ll_iter_value(struct linkedlist_iter *iter); +size_t *ll_iter_rvalue(struct linkedlist_iter *iter); +size_t ll_iter_index(struct linkedlist_iter *iter); +struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter); +struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); +void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); +struct linkedlist_node *ll_head(struct linkedlist *_list_); +struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); +struct linkedlist_node *ll_tail(struct linkedlist *_list_); +_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); +_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); +_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); +_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); +struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); +struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); +_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr); +_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_LINKEDLIST_TEST_H */ diff --git a/tests/include/tst_cmc_list.h b/tests/include/tst_cmc_list.h index f7def9b..3a1043d 100644 --- a/tests/include/tst_cmc_list.h +++ b/tests/include/tst_cmc_list.h @@ -1,11 +1,82 @@ - #ifndef CMC_CMC_LIST_TEST_H - #define CMC_CMC_LIST_TEST_H +#ifndef CMC_CMC_LIST_TEST_H +#define CMC_CMC_LIST_TEST_H - #include "macro_collections.h" - - struct list { size_t *buffer; size_t capacity; size_t count; int flag; struct list_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct list_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct list *l_new(size_t capacity, struct list_fval * f_val); struct list *l_new_custom(size_t capacity, struct list_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void l_clear(struct list * _list_); void l_free(struct list * _list_); void l_customize(struct list * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool l_push_front(struct list * _list_, size_t value); _Bool l_push_at(struct list * _list_, size_t value, size_t index); _Bool l_push_back(struct list * _list_, size_t value); _Bool l_pop_front(struct list * _list_); _Bool l_pop_at(struct list * _list_, size_t index); _Bool l_pop_back(struct list * _list_); size_t l_front(struct list * _list_); size_t l_get(struct list * _list_, size_t index); size_t *l_get_ref(struct list * _list_, size_t index); size_t l_back(struct list * _list_); size_t l_index_of(struct list * _list_, size_t value, _Bool from_start); _Bool l_contains(struct list * _list_, size_t value); _Bool l_empty(struct list * _list_); _Bool l_full(struct list * _list_); size_t l_count(struct list * _list_); _Bool l_fits(struct list * _list_, size_t size); size_t l_capacity(struct list * _list_); int l_flag(struct list * _list_); _Bool l_resize(struct list * _list_, size_t capacity); struct list *l_copy_of(struct list * _list_); _Bool l_equals(struct list * _list1_, struct list * _list2_); struct list_iter { struct list *target; size_t cursor; _Bool start; _Bool end; }; struct list_iter l_iter_start(struct list * target); struct list_iter l_iter_end(struct list * target); _Bool l_iter_at_start(struct list_iter * iter); _Bool l_iter_at_end(struct list_iter * iter); _Bool l_iter_to_start(struct list_iter * iter); _Bool l_iter_to_end(struct list_iter * iter); _Bool l_iter_next(struct list_iter * iter); _Bool l_iter_prev(struct list_iter * iter); _Bool l_iter_advance(struct list_iter * iter, size_t steps); _Bool l_iter_rewind(struct list_iter * iter, size_t steps); _Bool l_iter_go_to(struct list_iter * iter, size_t index); size_t l_iter_value(struct list_iter * iter); size_t *l_iter_rvalue(struct list_iter * iter); size_t l_iter_index(struct list_iter * iter); _Bool l_seq_push_front(struct list * _list_, size_t * values, size_t size); _Bool l_seq_push_at(struct list * _list_, size_t * values, size_t size, size_t index); _Bool l_seq_push_back(struct list * _list_, size_t * values, size_t size); _Bool l_seq_pop_at(struct list * _list_, size_t from, size_t to); struct list *l_seq_sublist(struct list * _list_, size_t from, size_t to); _Bool l_to_string(struct list * _list_, FILE * fptr); _Bool l_print(struct list * _list_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_LIST_TEST_H */ - \ No newline at end of file +struct list +{ + size_t *buffer; + size_t capacity; + size_t count; + int flag; + struct list_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct list_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct list *l_new(size_t capacity, struct list_fval *f_val); +struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void l_clear(struct list *_list_); +void l_free(struct list *_list_); +void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool l_push_front(struct list *_list_, size_t value); +_Bool l_push_at(struct list *_list_, size_t value, size_t index); +_Bool l_push_back(struct list *_list_, size_t value); +_Bool l_pop_front(struct list *_list_); +_Bool l_pop_at(struct list *_list_, size_t index); +_Bool l_pop_back(struct list *_list_); +size_t l_front(struct list *_list_); +size_t l_get(struct list *_list_, size_t index); +size_t *l_get_ref(struct list *_list_, size_t index); +size_t l_back(struct list *_list_); +size_t l_index_of(struct list *_list_, size_t value, _Bool from_start); +_Bool l_contains(struct list *_list_, size_t value); +_Bool l_empty(struct list *_list_); +_Bool l_full(struct list *_list_); +size_t l_count(struct list *_list_); +_Bool l_fits(struct list *_list_, size_t size); +size_t l_capacity(struct list *_list_); +int l_flag(struct list *_list_); +_Bool l_resize(struct list *_list_, size_t capacity); +struct list *l_copy_of(struct list *_list_); +_Bool l_equals(struct list *_list1_, struct list *_list2_); +struct list_iter +{ + struct list *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct list_iter l_iter_start(struct list *target); +struct list_iter l_iter_end(struct list *target); +_Bool l_iter_at_start(struct list_iter *iter); +_Bool l_iter_at_end(struct list_iter *iter); +_Bool l_iter_to_start(struct list_iter *iter); +_Bool l_iter_to_end(struct list_iter *iter); +_Bool l_iter_next(struct list_iter *iter); +_Bool l_iter_prev(struct list_iter *iter); +_Bool l_iter_advance(struct list_iter *iter, size_t steps); +_Bool l_iter_rewind(struct list_iter *iter, size_t steps); +_Bool l_iter_go_to(struct list_iter *iter, size_t index); +size_t l_iter_value(struct list_iter *iter); +size_t *l_iter_rvalue(struct list_iter *iter); +size_t l_iter_index(struct list_iter *iter); +_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); +_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); +_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); +struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); +_Bool l_to_string(struct list *_list_, FILE *fptr); +_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_LIST_TEST_H */ diff --git a/tests/include/tst_cmc_queue.h b/tests/include/tst_cmc_queue.h index 6cdcdc0..1fcd7b1 100644 --- a/tests/include/tst_cmc_queue.h +++ b/tests/include/tst_cmc_queue.h @@ -1,11 +1,71 @@ - #ifndef CMC_CMC_QUEUE_TEST_H - #define CMC_CMC_QUEUE_TEST_H +#ifndef CMC_CMC_QUEUE_TEST_H +#define CMC_CMC_QUEUE_TEST_H - #include "macro_collections.h" - - struct queue { size_t *buffer; size_t capacity; size_t count; size_t front; size_t back; int flag; struct queue_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct queue_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct queue *q_new(size_t capacity, struct queue_fval * f_val); struct queue *q_new_custom(size_t capacity, struct queue_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void q_clear(struct queue * _queue_); void q_free(struct queue * _queue_); void q_customize(struct queue * _queue_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool q_enqueue(struct queue * _queue_, size_t value); _Bool q_dequeue(struct queue * _queue_); size_t q_peek(struct queue * _queue_); _Bool q_contains(struct queue * _queue_, size_t value); _Bool q_empty(struct queue * _queue_); _Bool q_full(struct queue * _queue_); size_t q_count(struct queue * _queue_); size_t q_capacity(struct queue * _queue_); int q_flag(struct queue * _queue_); _Bool q_resize(struct queue * _queue_, size_t capacity); struct queue *q_copy_of(struct queue * _queue_); _Bool q_equals(struct queue * _queue1_, struct queue * _queue2_); struct queue_iter { struct queue *target; size_t cursor; size_t index; _Bool start; _Bool end; }; struct queue_iter q_iter_start(struct queue * target); struct queue_iter q_iter_end(struct queue * target); _Bool q_iter_at_start(struct queue_iter * iter); _Bool q_iter_at_end(struct queue_iter * iter); _Bool q_iter_to_start(struct queue_iter * iter); _Bool q_iter_to_end(struct queue_iter * iter); _Bool q_iter_next(struct queue_iter * iter); _Bool q_iter_prev(struct queue_iter * iter); _Bool q_iter_advance(struct queue_iter * iter, size_t steps); _Bool q_iter_rewind(struct queue_iter * iter, size_t steps); _Bool q_iter_go_to(struct queue_iter * iter, size_t index); size_t q_iter_value(struct queue_iter * iter); size_t *q_iter_rvalue(struct queue_iter * iter); size_t q_iter_index(struct queue_iter * iter); _Bool q_to_string(struct queue * _queue_, FILE * fptr); _Bool q_print(struct queue * _queue_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_QUEUE_TEST_H */ - \ No newline at end of file +struct queue +{ + size_t *buffer; + size_t capacity; + size_t count; + size_t front; + size_t back; + int flag; + struct queue_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct queue_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct queue *q_new(size_t capacity, struct queue_fval *f_val); +struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void q_clear(struct queue *_queue_); +void q_free(struct queue *_queue_); +void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool q_enqueue(struct queue *_queue_, size_t value); +_Bool q_dequeue(struct queue *_queue_); +size_t q_peek(struct queue *_queue_); +_Bool q_contains(struct queue *_queue_, size_t value); +_Bool q_empty(struct queue *_queue_); +_Bool q_full(struct queue *_queue_); +size_t q_count(struct queue *_queue_); +size_t q_capacity(struct queue *_queue_); +int q_flag(struct queue *_queue_); +_Bool q_resize(struct queue *_queue_, size_t capacity); +struct queue *q_copy_of(struct queue *_queue_); +_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_); +struct queue_iter +{ + struct queue *target; + size_t cursor; + size_t index; + _Bool start; + _Bool end; +}; +struct queue_iter q_iter_start(struct queue *target); +struct queue_iter q_iter_end(struct queue *target); +_Bool q_iter_at_start(struct queue_iter *iter); +_Bool q_iter_at_end(struct queue_iter *iter); +_Bool q_iter_to_start(struct queue_iter *iter); +_Bool q_iter_to_end(struct queue_iter *iter); +_Bool q_iter_next(struct queue_iter *iter); +_Bool q_iter_prev(struct queue_iter *iter); +_Bool q_iter_advance(struct queue_iter *iter, size_t steps); +_Bool q_iter_rewind(struct queue_iter *iter, size_t steps); +_Bool q_iter_go_to(struct queue_iter *iter, size_t index); +size_t q_iter_value(struct queue_iter *iter); +size_t *q_iter_rvalue(struct queue_iter *iter); +size_t q_iter_index(struct queue_iter *iter); +_Bool q_to_string(struct queue *_queue_, FILE *fptr); +_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_QUEUE_TEST_H */ diff --git a/tests/include/tst_cmc_sortedlist.h b/tests/include/tst_cmc_sortedlist.h index 2b4e0bf..a34b155 100644 --- a/tests/include/tst_cmc_sortedlist.h +++ b/tests/include/tst_cmc_sortedlist.h @@ -1,11 +1,72 @@ - #ifndef CMC_CMC_SORTEDLIST_TEST_H - #define CMC_CMC_SORTEDLIST_TEST_H +#ifndef CMC_CMC_SORTEDLIST_TEST_H +#define CMC_CMC_SORTEDLIST_TEST_H - #include "macro_collections.h" - - struct sortedlist { size_t *buffer; size_t capacity; size_t count; _Bool is_sorted; int flag; struct sortedlist_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct sortedlist_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval * f_val); struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void sl_clear(struct sortedlist * _list_); void sl_free(struct sortedlist * _list_); void sl_customize(struct sortedlist * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool sl_insert(struct sortedlist * _list_, size_t value); _Bool sl_remove(struct sortedlist * _list_, size_t index); size_t sl_max(struct sortedlist * _list_); size_t sl_min(struct sortedlist * _list_); size_t sl_get(struct sortedlist * _list_, size_t index); size_t sl_index_of(struct sortedlist * _list_, size_t value, _Bool from_start); _Bool sl_contains(struct sortedlist * _list_, size_t value); _Bool sl_empty(struct sortedlist * _list_); _Bool sl_full(struct sortedlist * _list_); size_t sl_count(struct sortedlist * _list_); size_t sl_capacity(struct sortedlist * _list_); int sl_flag(struct sortedlist * _list_); _Bool sl_resize(struct sortedlist * _list_, size_t capacity); void sl_sort(struct sortedlist * _list_); struct sortedlist *sl_copy_of(struct sortedlist * _list_); _Bool sl_equals(struct sortedlist * _list1_, struct sortedlist * _list2_); struct sortedlist_iter { struct sortedlist *target; size_t cursor; _Bool start; _Bool end; }; struct sortedlist_iter sl_iter_start(struct sortedlist * target); struct sortedlist_iter sl_iter_end(struct sortedlist * target); _Bool sl_iter_at_start(struct sortedlist_iter * iter); _Bool sl_iter_at_end(struct sortedlist_iter * iter); _Bool sl_iter_to_start(struct sortedlist_iter * iter); _Bool sl_iter_to_end(struct sortedlist_iter * iter); _Bool sl_iter_next(struct sortedlist_iter * iter); _Bool sl_iter_prev(struct sortedlist_iter * iter); _Bool sl_iter_advance(struct sortedlist_iter * iter, size_t steps); _Bool sl_iter_rewind(struct sortedlist_iter * iter, size_t steps); _Bool sl_iter_go_to(struct sortedlist_iter * iter, size_t index); size_t sl_iter_value(struct sortedlist_iter * iter); size_t sl_iter_index(struct sortedlist_iter * iter); _Bool sl_to_string(struct sortedlist * _list_, FILE * fptr); _Bool sl_print(struct sortedlist * _list_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_SORTEDLIST_TEST_H */ - \ No newline at end of file +struct sortedlist +{ + size_t *buffer; + size_t capacity; + size_t count; + _Bool is_sorted; + int flag; + struct sortedlist_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct sortedlist_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val); +struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void sl_clear(struct sortedlist *_list_); +void sl_free(struct sortedlist *_list_); +void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool sl_insert(struct sortedlist *_list_, size_t value); +_Bool sl_remove(struct sortedlist *_list_, size_t index); +size_t sl_max(struct sortedlist *_list_); +size_t sl_min(struct sortedlist *_list_); +size_t sl_get(struct sortedlist *_list_, size_t index); +size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start); +_Bool sl_contains(struct sortedlist *_list_, size_t value); +_Bool sl_empty(struct sortedlist *_list_); +_Bool sl_full(struct sortedlist *_list_); +size_t sl_count(struct sortedlist *_list_); +size_t sl_capacity(struct sortedlist *_list_); +int sl_flag(struct sortedlist *_list_); +_Bool sl_resize(struct sortedlist *_list_, size_t capacity); +void sl_sort(struct sortedlist *_list_); +struct sortedlist *sl_copy_of(struct sortedlist *_list_); +_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_); +struct sortedlist_iter +{ + struct sortedlist *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct sortedlist_iter sl_iter_start(struct sortedlist *target); +struct sortedlist_iter sl_iter_end(struct sortedlist *target); +_Bool sl_iter_at_start(struct sortedlist_iter *iter); +_Bool sl_iter_at_end(struct sortedlist_iter *iter); +_Bool sl_iter_to_start(struct sortedlist_iter *iter); +_Bool sl_iter_to_end(struct sortedlist_iter *iter); +_Bool sl_iter_next(struct sortedlist_iter *iter); +_Bool sl_iter_prev(struct sortedlist_iter *iter); +_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps); +_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps); +_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index); +size_t sl_iter_value(struct sortedlist_iter *iter); +size_t sl_iter_index(struct sortedlist_iter *iter); +_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr); +_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_SORTEDLIST_TEST_H */ diff --git a/tests/include/tst_cmc_stack.h b/tests/include/tst_cmc_stack.h index 0def578..6f510d0 100644 --- a/tests/include/tst_cmc_stack.h +++ b/tests/include/tst_cmc_stack.h @@ -1,11 +1,68 @@ - #ifndef CMC_CMC_STACK_TEST_H - #define CMC_CMC_STACK_TEST_H +#ifndef CMC_CMC_STACK_TEST_H +#define CMC_CMC_STACK_TEST_H - #include "macro_collections.h" - - struct stack { size_t *buffer; size_t capacity; size_t count; int flag; struct stack_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct stack_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct stack *s_new(size_t capacity, struct stack_fval * f_val); struct stack *s_new_custom(size_t capacity, struct stack_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void s_clear(struct stack * _stack_); void s_free(struct stack * _stack_); void s_customize(struct stack * _stack_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool s_push(struct stack * _stack_, size_t value); _Bool s_pop(struct stack * _stack_); size_t s_top(struct stack * _stack_); _Bool s_contains(struct stack * _stack_, size_t value); _Bool s_empty(struct stack * _stack_); _Bool s_full(struct stack * _stack_); size_t s_count(struct stack * _stack_); size_t s_capacity(struct stack * _stack_); int s_flag(struct stack * _stack_); _Bool s_resize(struct stack * _stack_, size_t capacity); struct stack *s_copy_of(struct stack * _stack_); _Bool s_equals(struct stack * _stack1_, struct stack * _stack2_); struct stack_iter { struct stack *target; size_t cursor; _Bool start; _Bool end; }; struct stack_iter s_iter_start(struct stack * target); struct stack_iter s_iter_end(struct stack * target); _Bool s_iter_at_start(struct stack_iter * iter); _Bool s_iter_at_end(struct stack_iter * iter); _Bool s_iter_to_start(struct stack_iter * iter); _Bool s_iter_to_end(struct stack_iter * iter); _Bool s_iter_next(struct stack_iter * iter); _Bool s_iter_prev(struct stack_iter * iter); _Bool s_iter_advance(struct stack_iter * iter, size_t steps); _Bool s_iter_rewind(struct stack_iter * iter, size_t steps); _Bool s_iter_go_to(struct stack_iter * iter, size_t index); size_t s_iter_value(struct stack_iter * iter); size_t *s_iter_rvalue(struct stack_iter * iter); size_t s_iter_index(struct stack_iter * iter); _Bool s_to_string(struct stack * _stack_, FILE * fptr); _Bool s_print(struct stack * _stack_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_STACK_TEST_H */ - \ No newline at end of file +struct stack +{ + size_t *buffer; + size_t capacity; + size_t count; + int flag; + struct stack_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct stack_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct stack *s_new(size_t capacity, struct stack_fval *f_val); +struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void s_clear(struct stack *_stack_); +void s_free(struct stack *_stack_); +void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool s_push(struct stack *_stack_, size_t value); +_Bool s_pop(struct stack *_stack_); +size_t s_top(struct stack *_stack_); +_Bool s_contains(struct stack *_stack_, size_t value); +_Bool s_empty(struct stack *_stack_); +_Bool s_full(struct stack *_stack_); +size_t s_count(struct stack *_stack_); +size_t s_capacity(struct stack *_stack_); +int s_flag(struct stack *_stack_); +_Bool s_resize(struct stack *_stack_, size_t capacity); +struct stack *s_copy_of(struct stack *_stack_); +_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_); +struct stack_iter +{ + struct stack *target; + size_t cursor; + _Bool start; + _Bool end; +}; +struct stack_iter s_iter_start(struct stack *target); +struct stack_iter s_iter_end(struct stack *target); +_Bool s_iter_at_start(struct stack_iter *iter); +_Bool s_iter_at_end(struct stack_iter *iter); +_Bool s_iter_to_start(struct stack_iter *iter); +_Bool s_iter_to_end(struct stack_iter *iter); +_Bool s_iter_next(struct stack_iter *iter); +_Bool s_iter_prev(struct stack_iter *iter); +_Bool s_iter_advance(struct stack_iter *iter, size_t steps); +_Bool s_iter_rewind(struct stack_iter *iter, size_t steps); +_Bool s_iter_go_to(struct stack_iter *iter, size_t index); +size_t s_iter_value(struct stack_iter *iter); +size_t *s_iter_rvalue(struct stack_iter *iter); +size_t s_iter_index(struct stack_iter *iter); +_Bool s_to_string(struct stack *_stack_, FILE *fptr); +_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_STACK_TEST_H */ diff --git a/tests/include/tst_cmc_treemap.h b/tests/include/tst_cmc_treemap.h index d13e622..005ad91 100644 --- a/tests/include/tst_cmc_treemap.h +++ b/tests/include/tst_cmc_treemap.h @@ -1,11 +1,92 @@ - #ifndef CMC_CMC_TREEMAP_TEST_H - #define CMC_CMC_TREEMAP_TEST_H +#ifndef CMC_CMC_TREEMAP_TEST_H +#define CMC_CMC_TREEMAP_TEST_H - #include "macro_collections.h" - - struct treemap { struct treemap_node * root; size_t count; int flag; struct treemap_fkey * f_key; struct treemap_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct treemap_node { size_t key; size_t value; unsigned char height; struct treemap_node * right; struct treemap_node * left; struct treemap_node * parent; }; struct treemap_fkey { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct treemap_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct treemap *tm_new(struct treemap_fkey * f_key, struct treemap_fval * f_val); struct treemap *tm_new_custom(struct treemap_fkey * f_key, struct treemap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void tm_clear(struct treemap * _map_); void tm_free(struct treemap * _map_); void tm_customize(struct treemap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool tm_insert(struct treemap * _map_, size_t key, size_t value); _Bool tm_update(struct treemap * _map_, size_t key, size_t new_value, size_t * old_value); _Bool tm_remove(struct treemap * _map_, size_t key, size_t * out_value); _Bool tm_max(struct treemap * _map_, size_t * key, size_t * value); _Bool tm_min(struct treemap * _map_, size_t * key, size_t * value); size_t tm_get(struct treemap * _map_, size_t key); size_t *tm_get_ref(struct treemap * _map_, size_t key); _Bool tm_contains(struct treemap * _map_, size_t key); _Bool tm_empty(struct treemap * _map_); size_t tm_count(struct treemap * _map_); int tm_flag(struct treemap * _map_); struct treemap *tm_copy_of(struct treemap * _map_); _Bool tm_equals(struct treemap * _map1_, struct treemap * _map2_); struct treemap_iter { struct treemap *target; struct treemap_node * cursor; struct treemap_node * first; struct treemap_node * last; size_t index; _Bool start; _Bool end; }; struct treemap_iter tm_iter_start(struct treemap * target); struct treemap_iter tm_iter_end(struct treemap * target); _Bool tm_iter_at_start(struct treemap_iter * iter); _Bool tm_iter_at_end(struct treemap_iter * iter); _Bool tm_iter_to_start(struct treemap_iter * iter); _Bool tm_iter_to_end(struct treemap_iter * iter); _Bool tm_iter_next(struct treemap_iter * iter); _Bool tm_iter_prev(struct treemap_iter * iter); _Bool tm_iter_advance(struct treemap_iter * iter, size_t steps); _Bool tm_iter_rewind(struct treemap_iter * iter, size_t steps); _Bool tm_iter_go_to(struct treemap_iter * iter, size_t index); size_t tm_iter_key(struct treemap_iter * iter); size_t tm_iter_value(struct treemap_iter * iter); size_t *tm_iter_rvalue(struct treemap_iter * iter); size_t tm_iter_index(struct treemap_iter * iter); _Bool tm_to_string(struct treemap * _map_, FILE * fptr); _Bool tm_print(struct treemap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep); - +#include "macro_collections.h" - #endif /* CMC_CMC_TREEMAP_TEST_H */ - \ No newline at end of file +struct treemap +{ + struct treemap_node *root; + size_t count; + int flag; + struct treemap_fkey *f_key; + struct treemap_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct treemap_node +{ + size_t key; + size_t value; + unsigned char height; + struct treemap_node *right; + struct treemap_node *left; + struct treemap_node *parent; +}; +struct treemap_fkey +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct treemap_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val); +struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void tm_clear(struct treemap *_map_); +void tm_free(struct treemap *_map_); +void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool tm_insert(struct treemap *_map_, size_t key, size_t value); +_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value); +_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value); +_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value); +_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value); +size_t tm_get(struct treemap *_map_, size_t key); +size_t *tm_get_ref(struct treemap *_map_, size_t key); +_Bool tm_contains(struct treemap *_map_, size_t key); +_Bool tm_empty(struct treemap *_map_); +size_t tm_count(struct treemap *_map_); +int tm_flag(struct treemap *_map_); +struct treemap *tm_copy_of(struct treemap *_map_); +_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_); +struct treemap_iter +{ + struct treemap *target; + struct treemap_node *cursor; + struct treemap_node *first; + struct treemap_node *last; + size_t index; + _Bool start; + _Bool end; +}; +struct treemap_iter tm_iter_start(struct treemap *target); +struct treemap_iter tm_iter_end(struct treemap *target); +_Bool tm_iter_at_start(struct treemap_iter *iter); +_Bool tm_iter_at_end(struct treemap_iter *iter); +_Bool tm_iter_to_start(struct treemap_iter *iter); +_Bool tm_iter_to_end(struct treemap_iter *iter); +_Bool tm_iter_next(struct treemap_iter *iter); +_Bool tm_iter_prev(struct treemap_iter *iter); +_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps); +_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps); +_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index); +size_t tm_iter_key(struct treemap_iter *iter); +size_t tm_iter_value(struct treemap_iter *iter); +size_t *tm_iter_rvalue(struct treemap_iter *iter); +size_t tm_iter_index(struct treemap_iter *iter); +_Bool tm_to_string(struct treemap *_map_, FILE *fptr); +_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep); + +#endif /* CMC_CMC_TREEMAP_TEST_H */ diff --git a/tests/include/tst_cmc_treeset.h b/tests/include/tst_cmc_treeset.h index 3623f97..9bca697 100644 --- a/tests/include/tst_cmc_treeset.h +++ b/tests/include/tst_cmc_treeset.h @@ -1,11 +1,84 @@ - #ifndef CMC_CMC_TREESET_TEST_H - #define CMC_CMC_TREESET_TEST_H +#ifndef CMC_CMC_TREESET_TEST_H +#define CMC_CMC_TREESET_TEST_H - #include "macro_collections.h" - - struct treeset { struct treeset_node * root; size_t count; int flag; struct treeset_fval * f_val; struct cmc_alloc_node *alloc; struct cmc_callbacks *callbacks; }; struct treeset_node { size_t value; unsigned char height; struct treeset_node * right; struct treeset_node * left; struct treeset_node * parent; }; struct treeset_fval { int (*cmp)(size_t, size_t); size_t (*cpy)(size_t); _Bool (*str)(FILE *, size_t); void (*free)(size_t); size_t (*hash)(size_t); int (*pri)(size_t, size_t); }; struct treeset *ts_new(struct treeset_fval * f_val); struct treeset *ts_new_custom(struct treeset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); void ts_clear(struct treeset * _set_); void ts_free(struct treeset * _set_); void ts_customize(struct treeset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); _Bool ts_insert(struct treeset * _set_, size_t value); _Bool ts_remove(struct treeset * _set_, size_t value); _Bool ts_max(struct treeset * _set_, size_t * value); _Bool ts_min(struct treeset * _set_, size_t * value); _Bool ts_contains(struct treeset * _set_, size_t value); _Bool ts_empty(struct treeset * _set_); size_t ts_count(struct treeset * _set_); int ts_flag(struct treeset * _set_); struct treeset *ts_copy_of(struct treeset * _set_); _Bool ts_equals(struct treeset * _set1_, struct treeset * _set2_); struct treeset_iter { struct treeset *target; struct treeset_node * cursor; struct treeset_node * first; struct treeset_node * last; size_t index; _Bool start; _Bool end; }; struct treeset_iter ts_iter_start(struct treeset * target); struct treeset_iter ts_iter_end(struct treeset * target); _Bool ts_iter_at_start(struct treeset_iter * iter); _Bool ts_iter_at_end(struct treeset_iter * iter); _Bool ts_iter_to_start(struct treeset_iter * iter); _Bool ts_iter_to_end(struct treeset_iter * iter); _Bool ts_iter_next(struct treeset_iter * iter); _Bool ts_iter_prev(struct treeset_iter * iter); _Bool ts_iter_advance(struct treeset_iter * iter, size_t steps); _Bool ts_iter_rewind(struct treeset_iter * iter, size_t steps); _Bool ts_iter_go_to(struct treeset_iter * iter, size_t index); size_t ts_iter_value(struct treeset_iter * iter); size_t ts_iter_index(struct treeset_iter * iter); struct treeset *ts_union(struct treeset * _set1_, struct treeset * _set2_); struct treeset *ts_intersection(struct treeset * _set1_, struct treeset * _set2_); struct treeset *ts_difference(struct treeset * _set1_, struct treeset * _set2_); struct treeset *ts_symmetric_difference(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_subset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_superset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_proper_subset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_proper_superset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_is_disjointset(struct treeset * _set1_, struct treeset * _set2_); _Bool ts_to_string(struct treeset * _set_, FILE * fptr); _Bool ts_print(struct treeset * _set_, FILE * fptr, const char *start, const char *separator, const char *end); - +#include "macro_collections.h" - #endif /* CMC_CMC_TREESET_TEST_H */ - \ No newline at end of file +struct treeset +{ + struct treeset_node *root; + size_t count; + int flag; + struct treeset_fval *f_val; + struct cmc_alloc_node *alloc; + struct cmc_callbacks *callbacks; +}; +struct treeset_node +{ + size_t value; + unsigned char height; + struct treeset_node *right; + struct treeset_node *left; + struct treeset_node *parent; +}; +struct treeset_fval +{ + int (*cmp)(size_t, size_t); + size_t (*cpy)(size_t); + _Bool (*str)(FILE *, size_t); + void (*free)(size_t); + size_t (*hash)(size_t); + int (*pri)(size_t, size_t); +}; +struct treeset *ts_new(struct treeset_fval *f_val); +struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks); +void ts_clear(struct treeset *_set_); +void ts_free(struct treeset *_set_); +void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); +_Bool ts_insert(struct treeset *_set_, size_t value); +_Bool ts_remove(struct treeset *_set_, size_t value); +_Bool ts_max(struct treeset *_set_, size_t *value); +_Bool ts_min(struct treeset *_set_, size_t *value); +_Bool ts_contains(struct treeset *_set_, size_t value); +_Bool ts_empty(struct treeset *_set_); +size_t ts_count(struct treeset *_set_); +int ts_flag(struct treeset *_set_); +struct treeset *ts_copy_of(struct treeset *_set_); +_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); +struct treeset_iter +{ + struct treeset *target; + struct treeset_node *cursor; + struct treeset_node *first; + struct treeset_node *last; + size_t index; + _Bool start; + _Bool end; +}; +struct treeset_iter ts_iter_start(struct treeset *target); +struct treeset_iter ts_iter_end(struct treeset *target); +_Bool ts_iter_at_start(struct treeset_iter *iter); +_Bool ts_iter_at_end(struct treeset_iter *iter); +_Bool ts_iter_to_start(struct treeset_iter *iter); +_Bool ts_iter_to_end(struct treeset_iter *iter); +_Bool ts_iter_next(struct treeset_iter *iter); +_Bool ts_iter_prev(struct treeset_iter *iter); +_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps); +_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); +_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); +size_t ts_iter_value(struct treeset_iter *iter); +size_t ts_iter_index(struct treeset_iter *iter); +struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); +_Bool ts_to_string(struct treeset *_set_, FILE *fptr); +_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_CMC_TREESET_TEST_H */ diff --git a/tests/src/tst_cmc_bitset.c b/tests/src/tst_cmc_bitset.c index b995c83..1ae7c75 100644 --- a/tests/src/tst_cmc_bitset.c +++ b/tests/src/tst_cmc_bitset.c @@ -1,7 +1,294 @@ - #include "tst_cmc_bitset.h" +#include "tst_cmc_bitset.h" - - _Bool bs_impl_resize(struct bitset * _bitset_, size_t n_bits, _Bool do_resize); 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) { ; if (n_bits < 1) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset)); if (!_bitset_) return ((void *)0); _bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); if (!_bitset_->buffer) { alloc->free(_bitset_); return ((void *)0); } _bitset_->capacity = capacity; _bitset_->flag = CMC_FLAG_OK; _bitset_->alloc = alloc; (_bitset_)->callbacks = callbacks; return _bitset_; } struct bitset bs_init(size_t n_bits) { return bs_init_custom(n_bits, ((void *)0), ((void *)0)); } struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node * alloc, struct cmc_callbacks * __attribute__((__unused__))(callbacks)) { ; struct bitset _bitset_ = { 0 }; if (n_bits < 1) return _bitset_; if (!alloc) alloc = &cmc_alloc_node_default; size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); if (!_bitset_.buffer) return _bitset_; _bitset_.capacity = capacity; _bitset_.flag = CMC_FLAG_OK; _bitset_.alloc = alloc; (&_bitset_)->callbacks = callbacks; return _bitset_; } void bs_free(struct bitset * _bitset_) { free(_bitset_->buffer); free(_bitset_); } void bs_release(struct bitset _bitset_) { free(_bitset_.buffer); } void bs_customize(struct bitset * _bitset_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _bitset_->alloc = &cmc_alloc_node_default; else _bitset_->alloc = alloc; (_bitset_)->callbacks = callbacks; _bitset_->flag = CMC_FLAG_OK; } _Bool bs_set(struct bitset * _bitset_, size_t bit_index) { if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) (_bitset_)->callbacks->create();; return 1; } _Bool bs_set_range(struct bitset * _bitset_, size_t from, size_t to) { if (to < from) { _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; size_t start_index = cmc_bidx_to_widx(from); size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; 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 1; } _Bool bs_clear(struct bitset * _bitset_, size_t bit_index) { if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) (_bitset_)->callbacks->delete();; return 1; } _Bool bs_clear_range(struct bitset * _bitset_, size_t from, size_t to) { if (to < from) { _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; size_t start_index = cmc_bidx_to_widx(from); size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; 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 1; } _Bool bs_flip(struct bitset * _bitset_, size_t bit_index) { if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) return 0; const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; size_t i = cmc_bidx_to_widx(bit_index); _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) (_bitset_)->callbacks->update();; return 1; } _Bool bs_flip_range(struct bitset * _bitset_, size_t from, size_t to) { if (to < from) { _bitset_->flag = CMC_FLAG_INVALID; return 0; } if (!bs_impl_resize(_bitset_, to + 1, 0)) return 0; size_t start_index = cmc_bidx_to_widx(from); size_t end_index = cmc_bidx_to_widx(to); const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; const cmc_bitset_word ones = ~((cmc_bitset_word)0); cmc_bitset_word shift_start = from % bits; 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 1; } _Bool bs_put(struct bitset * _bitset_, size_t bit_index, _Bool state) { if (state) return bs_set(_bitset_, bit_index); else return bs_clear(_bitset_, bit_index); } _Bool bs_put_range(struct bitset * _bitset_, size_t from, size_t to, _Bool state) { if (state) return bs_set_range(_bitset_, from, to); else return bs_clear_range(_bitset_, from, to); } _Bool bs_set_all(struct bitset * _bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = ~((cmc_bitset_word)0); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) (_bitset_)->callbacks->create();; return 1; } _Bool bs_clear_all(struct bitset * _bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] = 0; _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) (_bitset_)->callbacks->delete();; return 1; } _Bool bs_flip_all(struct bitset * _bitset_) { for (size_t i = 0; i < _bitset_->capacity; i++) _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); _bitset_->flag = CMC_FLAG_OK; if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) (_bitset_)->callbacks->create();; return 1; } _Bool bs_get(struct bitset * _bitset_, size_t bit_index) { const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; return w & ((cmc_bitset_word)1 << (bit_index % bits)); } _Bool bs_resize(struct bitset * _bitset_, size_t n_bits) { return bs_impl_resize(_bitset_, n_bits, 1); } _Bool bs_impl_resize(struct bitset * _bitset_, size_t n_bits, _Bool do_resize) { if (n_bits == 0) { _bitset_->flag = CMC_FLAG_INVALID; return 0; } size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; if (!do_resize && words <= _bitset_->capacity) return 1; cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); if (!new_buffer) { _bitset_->flag = CMC_FLAG_ALLOC; return 0; } _bitset_->buffer = new_buffer; 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 1; } - - \ No newline at end of file +_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize); +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) +{ + ; + if (n_bits < 1) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; + struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset)); + if (!_bitset_) + return ((void *)0); + _bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); + if (!_bitset_->buffer) + { + alloc->free(_bitset_); + return ((void *)0); + } + _bitset_->capacity = capacity; + _bitset_->flag = CMC_FLAG_OK; + _bitset_->alloc = alloc; + (_bitset_)->callbacks = callbacks; + return _bitset_; +} +struct bitset bs_init(size_t n_bits) +{ + return bs_init_custom(n_bits, ((void *)0), ((void *)0)); +} +struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, + struct cmc_callbacks *__attribute__((__unused__)) (callbacks)) +{ + ; + struct bitset _bitset_ = { 0 }; + if (n_bits < 1) + return _bitset_; + if (!alloc) + alloc = &cmc_alloc_node_default; + size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; + _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); + if (!_bitset_.buffer) + return _bitset_; + _bitset_.capacity = capacity; + _bitset_.flag = CMC_FLAG_OK; + _bitset_.alloc = alloc; + (&_bitset_)->callbacks = callbacks; + return _bitset_; +} +void bs_free(struct bitset *_bitset_) +{ + free(_bitset_->buffer); + free(_bitset_); +} +void bs_release(struct bitset _bitset_) +{ + free(_bitset_.buffer); +} +void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _bitset_->alloc = &cmc_alloc_node_default; + else + _bitset_->alloc = alloc; + (_bitset_)->callbacks = callbacks; + _bitset_->flag = CMC_FLAG_OK; +} +_Bool bs_set(struct bitset *_bitset_, size_t bit_index) +{ + if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) + return 0; + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; + size_t i = cmc_bidx_to_widx(bit_index); + _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); + _bitset_->flag = CMC_FLAG_OK; + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; + return 1; +} +_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) +{ + if (to < from) + { + _bitset_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!bs_impl_resize(_bitset_, to + 1, 0)) + return 0; + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; + const cmc_bitset_word ones = ~((cmc_bitset_word)0); + cmc_bitset_word shift_start = from % bits; + 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 1; +} +_Bool bs_clear(struct bitset *_bitset_, size_t bit_index) +{ + if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) + return 0; + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; + size_t i = cmc_bidx_to_widx(bit_index); + _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); + _bitset_->flag = CMC_FLAG_OK; + if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) + (_bitset_)->callbacks->delete (); + ; + return 1; +} +_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) +{ + if (to < from) + { + _bitset_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!bs_impl_resize(_bitset_, to + 1, 0)) + return 0; + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; + const cmc_bitset_word ones = ~((cmc_bitset_word)0); + cmc_bitset_word shift_start = from % bits; + 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 1; +} +_Bool bs_flip(struct bitset *_bitset_, size_t bit_index) +{ + if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) + return 0; + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; + size_t i = cmc_bidx_to_widx(bit_index); + _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); + _bitset_->flag = CMC_FLAG_OK; + if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) + (_bitset_)->callbacks->update(); + ; + return 1; +} +_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) +{ + if (to < from) + { + _bitset_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!bs_impl_resize(_bitset_, to + 1, 0)) + return 0; + size_t start_index = cmc_bidx_to_widx(from); + size_t end_index = cmc_bidx_to_widx(to); + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; + const cmc_bitset_word ones = ~((cmc_bitset_word)0); + cmc_bitset_word shift_start = from % bits; + 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 1; +} +_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state) +{ + if (state) + return bs_set(_bitset_, bit_index); + else + return bs_clear(_bitset_, bit_index); +} +_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state) +{ + if (state) + return bs_set_range(_bitset_, from, to); + else + return bs_clear_range(_bitset_, from, to); +} +_Bool bs_set_all(struct bitset *_bitset_) +{ + for (size_t i = 0; i < _bitset_->capacity; i++) + _bitset_->buffer[i] = ~((cmc_bitset_word)0); + _bitset_->flag = CMC_FLAG_OK; + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; + return 1; +} +_Bool bs_clear_all(struct bitset *_bitset_) +{ + for (size_t i = 0; i < _bitset_->capacity; i++) + _bitset_->buffer[i] = 0; + _bitset_->flag = CMC_FLAG_OK; + if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) + (_bitset_)->callbacks->delete (); + ; + return 1; +} +_Bool bs_flip_all(struct bitset *_bitset_) +{ + for (size_t i = 0; i < _bitset_->capacity; i++) + _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); + _bitset_->flag = CMC_FLAG_OK; + if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) + (_bitset_)->callbacks->create(); + ; + return 1; +} +_Bool bs_get(struct bitset *_bitset_, size_t bit_index) +{ + const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; + cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; + return w & ((cmc_bitset_word)1 << (bit_index % bits)); +} +_Bool bs_resize(struct bitset *_bitset_, size_t n_bits) +{ + return bs_impl_resize(_bitset_, n_bits, 1); +} +_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) +{ + if (n_bits == 0) + { + _bitset_->flag = CMC_FLAG_INVALID; + return 0; + } + size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; + if (!do_resize && words <= _bitset_->capacity) + return 1; + cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); + if (!new_buffer) + { + _bitset_->flag = CMC_FLAG_ALLOC; + return 0; + } + _bitset_->buffer = new_buffer; + 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 1; +} diff --git a/tests/src/tst_cmc_deque.c b/tests/src/tst_cmc_deque.c index e67e9d7..a815278 100644 --- a/tests/src/tst_cmc_deque.c +++ b/tests/src/tst_cmc_deque.c @@ -1,7 +1,516 @@ - #include "tst_cmc_deque.h" +#include "tst_cmc_deque.h" - - 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 cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct deque *_deque_ = alloc->malloc(sizeof(struct deque)); if (!_deque_) return ((void *)0); _deque_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_deque_->buffer) { alloc->free(_deque_); return ((void *)0); } _deque_->capacity = capacity; _deque_->count = 0; _deque_->front = 0; _deque_->back = 0; _deque_->flag = CMC_FLAG_OK; _deque_->f_val = f_val; _deque_->alloc = alloc; (_deque_)->callbacks = callbacks; return _deque_; } void d_clear(struct deque * _deque_) { if (_deque_->f_val->free) { for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { _deque_->f_val->free(_deque_->buffer[i]); i = (i + 1) % _deque_->capacity; } } memset(_deque_->buffer, 0, sizeof(size_t) * _deque_->capacity); _deque_->count = 0; _deque_->front = 0; _deque_->back = 0; _deque_->flag = CMC_FLAG_OK; } void d_free(struct deque * _deque_) { if (_deque_->f_val->free) { for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { _deque_->f_val->free(_deque_->buffer[i]); i = (i + 1) % _deque_->capacity; } } _deque_->alloc->free(_deque_->buffer); _deque_->alloc->free(_deque_); } void d_customize(struct deque * _deque_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _deque_->alloc = &cmc_alloc_node_default; else _deque_->alloc = alloc; (_deque_)->callbacks = callbacks; _deque_->flag = CMC_FLAG_OK; } _Bool d_push_front(struct deque * _deque_, size_t value) { if (d_full(_deque_)) { if (!d_resize(_deque_, _deque_->capacity * 2)) return 0; } _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 1; } _Bool d_push_back(struct deque * _deque_, size_t value) { if (d_full(_deque_)) { if (!d_resize(_deque_, _deque_->capacity * 2)) return 0; } _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 1; } _Bool d_pop_front(struct deque * _deque_) { if (d_empty(_deque_)) { _deque_->flag = CMC_FLAG_EMPTY; return 0; } _deque_->buffer[_deque_->front] = (size_t){ 0 }; _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; _deque_->count--; _deque_->flag = CMC_FLAG_OK; if ((_deque_)->callbacks && (_deque_)->callbacks->delete) (_deque_)->callbacks->delete();; return 1; } _Bool d_pop_back(struct deque * _deque_) { if (d_empty(_deque_)) { _deque_->flag = CMC_FLAG_EMPTY; return 0; } _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; _deque_->buffer[_deque_->back] = (size_t){ 0 }; _deque_->count--; _deque_->flag = CMC_FLAG_OK; if ((_deque_)->callbacks && (_deque_)->callbacks->delete) (_deque_)->callbacks->delete();; return 1; } size_t d_front(struct deque * _deque_) { if (d_empty(_deque_)) { _deque_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _deque_->flag = CMC_FLAG_OK; if ((_deque_)->callbacks && (_deque_)->callbacks->read) (_deque_)->callbacks->read();; return _deque_->buffer[_deque_->front]; } size_t d_back(struct deque * _deque_) { if (d_empty(_deque_)) { _deque_->flag = CMC_FLAG_EMPTY; return (size_t){ 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 d_contains(struct deque * _deque_, size_t value) { _deque_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) { result = 1; break; } i = (i + 1) % _deque_->capacity; } if ((_deque_)->callbacks && (_deque_)->callbacks->read) (_deque_)->callbacks->read();; return result; } _Bool d_empty(struct deque * _deque_) { return _deque_->count == 0; } _Bool d_full(struct deque * _deque_) { return _deque_->count >= _deque_->capacity; } size_t d_count(struct deque * _deque_) { return _deque_->count; } size_t d_capacity(struct deque * _deque_) { return _deque_->capacity; } int d_flag(struct deque * _deque_) { return _deque_->flag; } _Bool d_resize(struct deque * _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 0; } size_t *new_buffer = _deque_->alloc->malloc(sizeof(size_t) * capacity); if (!new_buffer) { _deque_->flag = CMC_FLAG_ALLOC; return 0; } 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 1; } struct deque *d_copy_of(struct deque * _deque_) { struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0)); if (!result) { _deque_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _deque_->callbacks; if (_deque_->f_val->cpy) { for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { 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 d_equals(struct deque * _deque1_, struct deque * _deque2_) { _deque1_->flag = CMC_FLAG_OK; _deque2_->flag = CMC_FLAG_OK; 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++) { if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) return 0; i = (i + 1) % _deque1_->capacity; j = (j + 1) % _deque2_->capacity; } return 1; } struct deque d_init(size_t capacity, struct deque_fval * f_val) { return d_init_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct deque d_init_custom(size_t capacity, struct deque_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; struct deque _deque_ = { 0 }; if (capacity < 1) return _deque_; if (!f_val) return _deque_; if (!alloc) alloc = &cmc_alloc_node_default; _deque_.buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_deque_.buffer) return _deque_; _deque_.capacity = capacity; _deque_.count = 0; _deque_.front = 0; _deque_.back = 0; _deque_.flag = CMC_FLAG_OK; _deque_.f_val = f_val; _deque_.alloc = alloc; (&_deque_)->callbacks = callbacks; return _deque_; } void d_release(struct deque _deque_) { if (_deque_.f_val->free) { for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) { _deque_.f_val->free(_deque_.buffer[i]); i = (i + 1) % _deque_.capacity; } } _deque_.alloc->free(_deque_.buffer); } struct deque_iter d_iter_start(struct deque * target) { struct deque_iter iter; iter.target = target; iter.cursor = target->front; iter.index = 0; iter.start = 1; iter.end = d_empty(target); return iter; } struct deque_iter d_iter_end(struct deque * target) { struct deque_iter iter; iter.target = target; if (!d_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 = d_empty(target); iter.end = 1; return iter; } _Bool d_iter_at_start(struct deque_iter * iter) { return d_empty(iter->target) || iter->start; } _Bool d_iter_at_end(struct deque_iter * iter) { return d_empty(iter->target) || iter->end; } _Bool d_iter_to_start(struct deque_iter * iter) { if (!d_empty(iter->target)) { iter->cursor = iter->target->front; iter->index = 0; iter->start = 1; iter->end = 0; return 1; } return 0; } _Bool d_iter_to_end(struct deque_iter * iter) { if (!d_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 = 0; iter->end = 1; return 1; } return 0; } _Bool d_iter_next(struct deque_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = d_empty(iter->target); iter->cursor = (iter->cursor + 1) % (iter->target->capacity); iter->index++; return 1; } _Bool d_iter_prev(struct deque_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = d_empty(iter->target); iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; iter->index--; return 1; } _Bool d_iter_advance(struct deque_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; iter->start = d_empty(iter->target); iter->index += steps; iter->cursor = (iter->cursor + steps) % iter->target->capacity; return 1; } _Bool d_iter_rewind(struct deque_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; iter->end = d_empty(iter->target); iter->index -= steps; if (iter->cursor < steps) iter->cursor += iter->target->capacity; iter->cursor -= steps; return 1; } _Bool d_iter_go_to(struct deque_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return d_iter_rewind(iter, iter->index - index); else if (iter->index < index) return d_iter_advance(iter, index - iter->index); return 1; } size_t d_iter_value(struct deque_iter * iter) { if (d_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t *d_iter_rvalue(struct deque_iter * iter) { if (d_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor]); } size_t d_iter_index(struct deque_iter * iter) { return iter->index; } _Bool d_to_string(struct deque * _deque_, FILE * fptr) { struct deque *d_ = _deque_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "front:%" "I64u" ", " "back:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag, d_->f_val, d_->alloc, (d_)->callbacks); } _Bool d_print(struct deque * _deque_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) { if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) return 0; i = (i + 1) % _deque_->capacity; if (j + 1 < _deque_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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 cmc_callbacks *callbacks) +{ + ; + if (capacity < 1) + return ((void *)0); + if (!f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct deque *_deque_ = alloc->malloc(sizeof(struct deque)); + if (!_deque_) + return ((void *)0); + _deque_->buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_deque_->buffer) + { + alloc->free(_deque_); + return ((void *)0); + } + _deque_->capacity = capacity; + _deque_->count = 0; + _deque_->front = 0; + _deque_->back = 0; + _deque_->flag = CMC_FLAG_OK; + _deque_->f_val = f_val; + _deque_->alloc = alloc; + (_deque_)->callbacks = callbacks; + return _deque_; +} +void d_clear(struct deque *_deque_) +{ + if (_deque_->f_val->free) + { + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + _deque_->f_val->free(_deque_->buffer[i]); + i = (i + 1) % _deque_->capacity; + } + } + memset(_deque_->buffer, 0, sizeof(size_t) * _deque_->capacity); + _deque_->count = 0; + _deque_->front = 0; + _deque_->back = 0; + _deque_->flag = CMC_FLAG_OK; +} +void d_free(struct deque *_deque_) +{ + if (_deque_->f_val->free) + { + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + _deque_->f_val->free(_deque_->buffer[i]); + i = (i + 1) % _deque_->capacity; + } + } + _deque_->alloc->free(_deque_->buffer); + _deque_->alloc->free(_deque_); +} +void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _deque_->alloc = &cmc_alloc_node_default; + else + _deque_->alloc = alloc; + (_deque_)->callbacks = callbacks; + _deque_->flag = CMC_FLAG_OK; +} +_Bool d_push_front(struct deque *_deque_, size_t value) +{ + if (d_full(_deque_)) + { + if (!d_resize(_deque_, _deque_->capacity * 2)) + return 0; + } + _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 1; +} +_Bool d_push_back(struct deque *_deque_, size_t value) +{ + if (d_full(_deque_)) + { + if (!d_resize(_deque_, _deque_->capacity * 2)) + return 0; + } + _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 1; +} +_Bool d_pop_front(struct deque *_deque_) +{ + if (d_empty(_deque_)) + { + _deque_->flag = CMC_FLAG_EMPTY; + return 0; + } + _deque_->buffer[_deque_->front] = (size_t){ 0 }; + _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; + _deque_->count--; + _deque_->flag = CMC_FLAG_OK; + if ((_deque_)->callbacks && (_deque_)->callbacks->delete) + (_deque_)->callbacks->delete (); + ; + return 1; +} +_Bool d_pop_back(struct deque *_deque_) +{ + if (d_empty(_deque_)) + { + _deque_->flag = CMC_FLAG_EMPTY; + return 0; + } + _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; + _deque_->buffer[_deque_->back] = (size_t){ 0 }; + _deque_->count--; + _deque_->flag = CMC_FLAG_OK; + if ((_deque_)->callbacks && (_deque_)->callbacks->delete) + (_deque_)->callbacks->delete (); + ; + return 1; +} +size_t d_front(struct deque *_deque_) +{ + if (d_empty(_deque_)) + { + _deque_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _deque_->flag = CMC_FLAG_OK; + if ((_deque_)->callbacks && (_deque_)->callbacks->read) + (_deque_)->callbacks->read(); + ; + return _deque_->buffer[_deque_->front]; +} +size_t d_back(struct deque *_deque_) +{ + if (d_empty(_deque_)) + { + _deque_->flag = CMC_FLAG_EMPTY; + return (size_t){ 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 d_contains(struct deque *_deque_, size_t value) +{ + _deque_->flag = CMC_FLAG_OK; + _Bool result = 0; + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) + { + result = 1; + break; + } + i = (i + 1) % _deque_->capacity; + } + if ((_deque_)->callbacks && (_deque_)->callbacks->read) + (_deque_)->callbacks->read(); + ; + return result; +} +_Bool d_empty(struct deque *_deque_) +{ + return _deque_->count == 0; +} +_Bool d_full(struct deque *_deque_) +{ + return _deque_->count >= _deque_->capacity; +} +size_t d_count(struct deque *_deque_) +{ + return _deque_->count; +} +size_t d_capacity(struct deque *_deque_) +{ + return _deque_->capacity; +} +int d_flag(struct deque *_deque_) +{ + return _deque_->flag; +} +_Bool d_resize(struct deque *_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 0; + } + size_t *new_buffer = _deque_->alloc->malloc(sizeof(size_t) * capacity); + if (!new_buffer) + { + _deque_->flag = CMC_FLAG_ALLOC; + return 0; + } + 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 1; +} +struct deque *d_copy_of(struct deque *_deque_) +{ + struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0)); + if (!result) + { + _deque_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _deque_->callbacks; + if (_deque_->f_val->cpy) + { + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + 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 d_equals(struct deque *_deque1_, struct deque *_deque2_) +{ + _deque1_->flag = CMC_FLAG_OK; + _deque2_->flag = CMC_FLAG_OK; + 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++) + { + if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) + return 0; + i = (i + 1) % _deque1_->capacity; + j = (j + 1) % _deque2_->capacity; + } + return 1; +} +struct deque d_init(size_t capacity, struct deque_fval *f_val) +{ + return d_init_custom(capacity, f_val, ((void *)0), ((void *)0)); +} +struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + struct deque _deque_ = { 0 }; + if (capacity < 1) + return _deque_; + if (!f_val) + return _deque_; + if (!alloc) + alloc = &cmc_alloc_node_default; + _deque_.buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_deque_.buffer) + return _deque_; + _deque_.capacity = capacity; + _deque_.count = 0; + _deque_.front = 0; + _deque_.back = 0; + _deque_.flag = CMC_FLAG_OK; + _deque_.f_val = f_val; + _deque_.alloc = alloc; + (&_deque_)->callbacks = callbacks; + return _deque_; +} +void d_release(struct deque _deque_) +{ + if (_deque_.f_val->free) + { + for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) + { + _deque_.f_val->free(_deque_.buffer[i]); + i = (i + 1) % _deque_.capacity; + } + } + _deque_.alloc->free(_deque_.buffer); +} +struct deque_iter d_iter_start(struct deque *target) +{ + struct deque_iter iter; + iter.target = target; + iter.cursor = target->front; + iter.index = 0; + iter.start = 1; + iter.end = d_empty(target); + return iter; +} +struct deque_iter d_iter_end(struct deque *target) +{ + struct deque_iter iter; + iter.target = target; + if (!d_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 = d_empty(target); + iter.end = 1; + return iter; +} +_Bool d_iter_at_start(struct deque_iter *iter) +{ + return d_empty(iter->target) || iter->start; +} +_Bool d_iter_at_end(struct deque_iter *iter) +{ + return d_empty(iter->target) || iter->end; +} +_Bool d_iter_to_start(struct deque_iter *iter) +{ + if (!d_empty(iter->target)) + { + iter->cursor = iter->target->front; + iter->index = 0; + iter->start = 1; + iter->end = 0; + return 1; + } + return 0; +} +_Bool d_iter_to_end(struct deque_iter *iter) +{ + if (!d_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 = 0; + iter->end = 1; + return 1; + } + return 0; +} +_Bool d_iter_next(struct deque_iter *iter) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = d_empty(iter->target); + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); + iter->index++; + return 1; +} +_Bool d_iter_prev(struct deque_iter *iter) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + iter->end = d_empty(iter->target); + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; + iter->index--; + return 1; +} +_Bool d_iter_advance(struct deque_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + iter->start = d_empty(iter->target); + iter->index += steps; + iter->cursor = (iter->cursor + steps) % iter->target->capacity; + return 1; +} +_Bool d_iter_rewind(struct deque_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + iter->end = d_empty(iter->target); + iter->index -= steps; + if (iter->cursor < steps) + iter->cursor += iter->target->capacity; + iter->cursor -= steps; + return 1; +} +_Bool d_iter_go_to(struct deque_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return d_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return d_iter_advance(iter, index - iter->index); + return 1; +} +size_t d_iter_value(struct deque_iter *iter) +{ + if (d_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor]; +} +size_t *d_iter_rvalue(struct deque_iter *iter) +{ + if (d_empty(iter->target)) + return ((void *)0); + return &(iter->target->buffer[iter->cursor]); +} +size_t d_iter_index(struct deque_iter *iter) +{ + return iter->index; +} +_Bool d_to_string(struct deque *_deque_, FILE *fptr) +{ + struct deque *d_ = _deque_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "front:%" + "I64u" + ", " + "back:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag, + d_->f_val, d_->alloc, (d_)->callbacks); +} +_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) + return 0; + i = (i + 1) % _deque_->capacity; + if (j + 1 < _deque_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_hashbidimap.c b/tests/src/tst_cmc_hashbidimap.c index 8b46a90..b7381c4 100644 --- a/tests/src/tst_cmc_hashbidimap.c +++ b/tests/src/tst_cmc_hashbidimap.c @@ -1,7 +1,856 @@ - #include "tst_cmc_hashbidimap.h" +#include "tst_cmc_hashbidimap.h" - - 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_fval * f_val) { return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey * f_key, struct hashbidimap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); size_t real_capacity = hbm_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); if (!_map_) return ((void *)0); _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_->buffer); alloc->free(_map_); return ((void *)0); } _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->flag = CMC_FLAG_OK; _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->it_start = hbm_impl_it_start; _map_->it_end = hbm_impl_it_end; return _map_; } void hbm_clear(struct hashbidimap * _map_) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashbidimap_entry *entry = _map_->buffer[i][0]; if (entry && entry != ((void *)1)) { if (_map_->f_key->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] = ((void *)0); _map_->buffer[i][1] = ((void *)0); } _map_->count = 0; _map_->flag = CMC_FLAG_OK; } void hbm_free(struct hashbidimap * _map_) { hbm_clear(_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) { ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hbm_insert(struct hashbidimap * _map_, size_t key, size_t value) { if (hbm_full(_map_)) { 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)) { _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); if (!key_entry || !val_entry) { if (key_entry) *key_entry = ((void *)1); if (val_entry) *val_entry = ((void *)1); _map_->alloc->free(entry); _map_->flag = CMC_FLAG_ERROR; return 0; } _map_->count++; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->create) (_map_)->callbacks->create();; return 1; } _Bool hbm_update_key(struct hashbidimap * _map_, size_t val, size_t new_key) { if (hbm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry * *key_entry, **val_entry; val_entry = hbm_impl_get_entry_by_val(_map_, val); if (!val_entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) goto success; if (hbm_impl_get_entry_by_key(_map_, new_key) != ((void *)0)) { _map_->flag = CMC_FLAG_DUPLICATE; return 0; } key_entry = (*val_entry)->ref[0]; if (!key_entry || *key_entry != *val_entry) { _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry *to_add = *key_entry; size_t tmp_key = to_add->key; to_add->key = new_key; *key_entry = ((void *)1); if (!hbm_impl_add_entry_to_key(_map_, to_add)) { to_add->key = tmp_key; *key_entry = to_add; _map_->flag = CMC_FLAG_ERROR; return 0; } success: _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->update) (_map_)->callbacks->update();; return 1; } _Bool hbm_update_val(struct hashbidimap * _map_, size_t key, size_t new_val) { if (hbm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry * *key_entry, **val_entry; key_entry = hbm_impl_get_entry_by_key(_map_, key); if (!key_entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) goto success; if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) { _map_->flag = CMC_FLAG_DUPLICATE; return 0; } val_entry = (*key_entry)->ref[1]; if (!val_entry || *val_entry != *key_entry) { _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry *to_add = *val_entry; size_t tmp_val = to_add->value; to_add->value = new_val; *val_entry = ((void *)1); if (!hbm_impl_add_entry_to_val(_map_, to_add)) { to_add->value = tmp_val; *val_entry = to_add; _map_->flag = CMC_FLAG_ERROR; return 0; } success: _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->update) (_map_)->callbacks->update();; return 1; } _Bool hbm_remove_by_key(struct hashbidimap * _map_, size_t key, size_t * out_key, size_t * out_val) { if (hbm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry * *key_entry, **val_entry; key_entry = hbm_impl_get_entry_by_key(_map_, key); if (!key_entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } val_entry = (*key_entry)->ref[1]; if (!val_entry || *val_entry != *key_entry) { _map_->flag = CMC_FLAG_ERROR; return 0; } if (out_key) *out_key = (*key_entry)->key; if (out_val) *out_val = (*key_entry)->value; _map_->alloc->free(*key_entry); *key_entry = ((void *)1); *val_entry = ((void *)1); _map_->count--; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->delete) (_map_)->callbacks->delete();; return 1; } _Bool hbm_remove_by_val(struct hashbidimap * _map_, size_t val, size_t * out_key, size_t * out_val) { if (hbm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashbidimap_entry * *key_entry, **val_entry; val_entry = hbm_impl_get_entry_by_val(_map_, val); if (!val_entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } key_entry = (*val_entry)->ref[0]; if (!key_entry || *key_entry != *val_entry) { _map_->flag = CMC_FLAG_ERROR; return 0; } if (out_key) *out_key = (*val_entry)->key; if (out_val) *out_val = (*val_entry)->value; _map_->alloc->free(*val_entry); *key_entry = ((void *)1); *val_entry = ((void *)1); _map_->count--; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->delete) (_map_)->callbacks->delete();; return 1; } size_t hbm_get_key(struct hashbidimap * _map_, size_t val) { struct hashbidimap_entry **entry = hbm_impl_get_entry_by_val(_map_, val); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return (*entry)->key; } size_t hbm_get_val(struct hashbidimap * _map_, size_t key) { struct hashbidimap_entry **entry = hbm_impl_get_entry_by_key(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return (*entry)->value; } _Bool hbm_contains_key(struct hashbidimap * _map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool hbm_contains_val(struct hashbidimap * _map_, size_t val) { _map_->flag = CMC_FLAG_OK; _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool hbm_empty(struct hashbidimap * _map_) { return _map_->count == 0; } _Bool hbm_full(struct hashbidimap * _map_) { return (double)_map_->capacity * _map_->load <= (double)_map_->count; } size_t hbm_count(struct hashbidimap * _map_) { return _map_->count; } size_t hbm_capacity(struct hashbidimap * _map_) { return _map_->capacity; } double hbm_load(struct hashbidimap * _map_) { return _map_->load; } int hbm_flag(struct hashbidimap * _map_) { return _map_->flag; } _Bool hbm_resize(struct hashbidimap * _map_, size_t capacity) { _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = CMC_FLAG_ERROR; return 0; } size_t new_cap = hbm_impl_calculate_size(capacity); if (new_cap < _map_->count / _map_->load) { _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashbidimap *_new_map_ = hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _map_->capacity; i++) { 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); if (!e1 || !e2) { _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); _map_->flag = CMC_FLAG_ERROR; return 0; } _new_map_->count++; } } if (_map_->count != _new_map_->count) { _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; _map_->alloc->free(_new_map_->buffer); _map_->alloc->free(_new_map_); _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashbidimap_entry * (*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 1; } struct hashbidimap *hbm_copy_of(struct hashbidimap * _map_) { struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _map_->callbacks; for (size_t i = 0; i < _map_->capacity; i++) { struct hashbidimap_entry *scan = _map_->buffer[i][0]; if (scan && scan != ((void *)1)) { size_t tmp_key; size_t 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; 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++; } } _map_->flag = CMC_FLAG_OK; return result; } _Bool hbm_equals(struct hashbidimap * _map1_, struct hashbidimap * _map2_) { _map1_->flag = CMC_FLAG_OK; _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashbidimap *_mapA_; struct hashbidimap *_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 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); if (!entry_B) return 0; if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) return 0; } } return 1; } struct hashbidimap_iter * hbm_iter_new(struct hashbidimap * target) { struct hashbidimap_iter *iter = target->alloc->malloc(sizeof(struct hashbidimap_iter)); if (!iter) return ((void *)0); hbm_iter_init(iter, target); return iter; } void hbm_iter_free(struct hashbidimap_iter * iter) { iter->target->alloc->free(iter); } void hbm_iter_init(struct hashbidimap_iter * iter, struct hashbidimap * target) { memset(iter, 0, sizeof(struct hashbidimap_iter)); iter->target = target; iter->start = 1; iter->end = hbm_empty(target); if (!hbm_empty(target)) { for (size_t i = 0; i < target->capacity; i++) { struct hashbidimap_entry *entry = target->buffer[i][0]; if (entry && entry != ((void *)1)) { iter->first = i; break; } } iter->cursor = iter->first; for (size_t i = target->capacity; i > 0; i--) { struct hashbidimap_entry *entry = target->buffer[i - 1][0]; if (entry && entry != ((void *)1)) { iter->last = i - 1; break; } } } } _Bool hbm_iter_start(struct hashbidimap_iter * iter) { return hbm_empty(iter->target) || iter->start; } _Bool hbm_iter_end(struct hashbidimap_iter * iter) { return hbm_empty(iter->target) || iter->end; } void hbm_iter_to_start(struct hashbidimap_iter * iter) { if (!hbm_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = 0; } } void hbm_iter_to_end(struct hashbidimap_iter * iter) { if (!hbm_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = 0; iter->end = 1; } } _Bool hbm_iter_next(struct hashbidimap_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = hbm_empty(iter->target); struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; iter->index++; while (1) { iter->cursor++; scan = iter->target->buffer[iter->cursor][0]; if (scan != ((void *)0) && scan != ((void *)1)) break; } return 1; } _Bool hbm_iter_prev(struct hashbidimap_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = hbm_empty(iter->target); struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; iter->index--; while (1) { iter->cursor--; scan = iter->target->buffer[iter->cursor][0]; if (scan != ((void *)0) && scan != ((void *)1)) break; } return 1; } _Bool hbm_iter_advance(struct hashbidimap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hbm_iter_next(iter); return 1; } _Bool hbm_iter_rewind(struct hashbidimap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hbm_iter_prev(iter); return 1; } _Bool hbm_iter_go_to(struct hashbidimap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hbm_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hbm_iter_advance(iter, index - iter->index); return 1; } size_t hbm_iter_key(struct hashbidimap_iter * iter) { if (hbm_empty(iter->target)) { iter->target->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } return iter->target->buffer[iter->cursor][0]->key; } size_t hbm_iter_value(struct hashbidimap_iter * iter) { if (hbm_empty(iter->target)) { iter->target->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } return iter->target->buffer[iter->cursor][0]->value; } 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) { struct hashbidimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashbidimap_entry)); if (!entry) return ((void *)0); entry->key = key; entry->value = value; entry->dist[0] = 0; entry->dist[1] = 0; entry->ref[0] = ((void *)0); entry->ref[1] = ((void *)0); return entry; } 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; struct hashbidimap_entry *target = _map_->buffer[pos][0]; while (target != ((void *)0)) { if (target != ((void *)1) && _map_->f_key->cmp(target->key, key) == 0) return &(_map_->buffer[pos % _map_->capacity][0]); pos++; target = _map_->buffer[pos % _map_->capacity][0]; } return ((void *)0); } 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; struct hashbidimap_entry *target = _map_->buffer[pos][1]; while (target != ((void *)0)) { if (target != ((void *)1) && _map_->f_val->cmp(target->value, val) == 0) return &(_map_->buffer[pos % _map_->capacity][1]); pos++; target = _map_->buffer[pos % _map_->capacity][1]; } return ((void *)0); } 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]); if (*scan == ((void *)0)) { *scan = entry; entry->ref[0] = scan; return scan; } else { while (1) { pos++; scan = &(_map_->buffer[pos % _map_->capacity][0]); if (*scan == ((void *)0) || *scan == ((void *)1)) { 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 hashbidimap_entry *_tmp_ = *scan; *scan = entry; entry = _tmp_; } } } return ((void *)0); } 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]); if (*scan == ((void *)0)) { *scan = entry; entry->ref[1] = scan; return scan; } else { while (1) { pos++; scan = &(_map_->buffer[pos % _map_->capacity][1]); if (*scan == ((void *)0) || *scan == ((void *)1)) { 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 hashbidimap_entry *_tmp_ = *scan; *scan = entry; entry = _tmp_; } } } return ((void *)0); } static size_t hbm_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 hashbidimap_iter hbm_impl_it_start(struct hashbidimap * _map_) { struct hashbidimap_iter iter; hbm_iter_init(&iter, _map_); return iter; } static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap * _map_) { struct hashbidimap_iter iter; hbm_iter_init(&iter, _map_); hbm_iter_to_end(&iter); return iter; } _Bool hbm_to_string(struct hashbidimap * _map_, FILE * fptr) { struct hashbidimap *m_ = _map_; return 0 <= fprintf(fptr, "struct %s<%s, %s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_key:%p, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } _Bool hbm_print(struct hashbidimap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep) { fprintf(fptr, "%s", start); size_t last = 0; for (size_t i = _map_->capacity; i > 0; i--) { struct hashbidimap_entry *entry = _map_->buffer[i - 1][0]; if (entry && entry != ((void *)1)) { last = i - 1; break; } } for (size_t i = 0; i < _map_->capacity; i++) { struct hashbidimap_entry *entry = _map_->buffer[i][0]; if (entry && entry != ((void *)1)) { if (!_map_->f_key->str(fptr, entry->key)) return 0; fprintf(fptr, "%s", key_val_sep); if (!_map_->f_val->str(fptr, entry->value)) return 0; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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_fval *f_val) +{ + return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); +} +struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, + struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (capacity == 0 || load <= 0 || load >= 1) + return ((void *)0); + if (capacity >= 0xffffffffffffffffULL * load) + return ((void *)0); + if (!f_key || !f_val) + return ((void *)0); + size_t real_capacity = hbm_impl_calculate_size(capacity / load); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); + if (!_map_) + return ((void *)0); + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); + if (!_map_->buffer) + { + alloc->free(_map_->buffer); + alloc->free(_map_); + return ((void *)0); + } + _map_->count = 0; + _map_->capacity = real_capacity; + _map_->load = load; + _map_->flag = CMC_FLAG_OK; + _map_->f_key = f_key; + _map_->f_val = f_val; + _map_->flag = CMC_FLAG_OK; + _map_->alloc = alloc; + (_map_)->callbacks = callbacks; + _map_->it_start = hbm_impl_it_start; + _map_->it_end = hbm_impl_it_end; + return _map_; +} +void hbm_clear(struct hashbidimap *_map_) +{ + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashbidimap_entry *entry = _map_->buffer[i][0]; + if (entry && entry != ((void *)1)) + { + if (_map_->f_key->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] = ((void *)0); + _map_->buffer[i][1] = ((void *)0); + } + _map_->count = 0; + _map_->flag = CMC_FLAG_OK; +} +void hbm_free(struct hashbidimap *_map_) +{ + hbm_clear(_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) +{ + ; + if (!alloc) + _map_->alloc = &cmc_alloc_node_default; + else + _map_->alloc = alloc; + (_map_)->callbacks = callbacks; + _map_->flag = CMC_FLAG_OK; +} +_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) +{ + if (hbm_full(_map_)) + { + 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)) + { + _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); + if (!key_entry || !val_entry) + { + if (key_entry) + *key_entry = ((void *)1); + if (val_entry) + *val_entry = ((void *)1); + _map_->alloc->free(entry); + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + _map_->count++; + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; + return 1; +} +_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) +{ + if (hbm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashbidimap_entry **key_entry, **val_entry; + val_entry = hbm_impl_get_entry_by_val(_map_, val); + if (!val_entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) + goto success; + if (hbm_impl_get_entry_by_key(_map_, new_key) != ((void *)0)) + { + _map_->flag = CMC_FLAG_DUPLICATE; + return 0; + } + key_entry = (*val_entry)->ref[0]; + if (!key_entry || *key_entry != *val_entry) + { + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + struct hashbidimap_entry *to_add = *key_entry; + size_t tmp_key = to_add->key; + to_add->key = new_key; + *key_entry = ((void *)1); + if (!hbm_impl_add_entry_to_key(_map_, to_add)) + { + to_add->key = tmp_key; + *key_entry = to_add; + _map_->flag = CMC_FLAG_ERROR; + return 0; + } +success: + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; + return 1; +} +_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) +{ + if (hbm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashbidimap_entry **key_entry, **val_entry; + key_entry = hbm_impl_get_entry_by_key(_map_, key); + if (!key_entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) + goto success; + if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) + { + _map_->flag = CMC_FLAG_DUPLICATE; + return 0; + } + val_entry = (*key_entry)->ref[1]; + if (!val_entry || *val_entry != *key_entry) + { + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + struct hashbidimap_entry *to_add = *val_entry; + size_t tmp_val = to_add->value; + to_add->value = new_val; + *val_entry = ((void *)1); + if (!hbm_impl_add_entry_to_val(_map_, to_add)) + { + to_add->value = tmp_val; + *val_entry = to_add; + _map_->flag = CMC_FLAG_ERROR; + return 0; + } +success: + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->update) + (_map_)->callbacks->update(); + ; + return 1; +} +_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val) +{ + if (hbm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashbidimap_entry **key_entry, **val_entry; + key_entry = hbm_impl_get_entry_by_key(_map_, key); + if (!key_entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + val_entry = (*key_entry)->ref[1]; + if (!val_entry || *val_entry != *key_entry) + { + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + if (out_key) + *out_key = (*key_entry)->key; + if (out_val) + *out_val = (*key_entry)->value; + _map_->alloc->free(*key_entry); + *key_entry = ((void *)1); + *val_entry = ((void *)1); + _map_->count--; + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; + return 1; +} +_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val) +{ + if (hbm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashbidimap_entry **key_entry, **val_entry; + val_entry = hbm_impl_get_entry_by_val(_map_, val); + if (!val_entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + key_entry = (*val_entry)->ref[0]; + if (!key_entry || *key_entry != *val_entry) + { + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + if (out_key) + *out_key = (*val_entry)->key; + if (out_val) + *out_val = (*val_entry)->value; + _map_->alloc->free(*val_entry); + *key_entry = ((void *)1); + *val_entry = ((void *)1); + _map_->count--; + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; + return 1; +} +size_t hbm_get_key(struct hashbidimap *_map_, size_t val) +{ + struct hashbidimap_entry **entry = hbm_impl_get_entry_by_val(_map_, val); + if (!entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return (size_t){ 0 }; + } + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return (*entry)->key; +} +size_t hbm_get_val(struct hashbidimap *_map_, size_t key) +{ + struct hashbidimap_entry **entry = hbm_impl_get_entry_by_key(_map_, key); + if (!entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return (size_t){ 0 }; + } + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return (*entry)->value; +} +_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key) +{ + _map_->flag = CMC_FLAG_OK; + _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return result; +} +_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val) +{ + _map_->flag = CMC_FLAG_OK; + _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return result; +} +_Bool hbm_empty(struct hashbidimap *_map_) +{ + return _map_->count == 0; +} +_Bool hbm_full(struct hashbidimap *_map_) +{ + return (double)_map_->capacity * _map_->load <= (double)_map_->count; +} +size_t hbm_count(struct hashbidimap *_map_) +{ + return _map_->count; +} +size_t hbm_capacity(struct hashbidimap *_map_) +{ + return _map_->capacity; +} +double hbm_load(struct hashbidimap *_map_) +{ + return _map_->load; +} +int hbm_flag(struct hashbidimap *_map_) +{ + return _map_->flag; +} +_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) +{ + _map_->flag = CMC_FLAG_OK; + if (_map_->capacity == capacity) + goto success; + if (_map_->capacity > capacity / _map_->load) + goto success; + if (capacity >= 0xffffffffffffffffULL * _map_->load) + { + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + size_t new_cap = hbm_impl_calculate_size(capacity); + if (new_cap < _map_->count / _map_->load) + { + _map_->flag = CMC_FLAG_INVALID; + return 0; + } + struct hashbidimap *_new_map_ = + hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); + if (!_new_map_) + { + _map_->flag = CMC_FLAG_ALLOC; + return 0; + } + for (size_t i = 0; i < _map_->capacity; i++) + { + 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); + if (!e1 || !e2) + { + _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; + _map_->alloc->free(_new_map_->buffer); + _map_->alloc->free(_new_map_); + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + _new_map_->count++; + } + } + if (_map_->count != _new_map_->count) + { + _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; + _map_->alloc->free(_new_map_->buffer); + _map_->alloc->free(_new_map_); + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + struct hashbidimap_entry *(*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 1; +} +struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) +{ + struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, + _map_->alloc, ((void *)0)); + if (!result) + { + _map_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _map_->callbacks; + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashbidimap_entry *scan = _map_->buffer[i][0]; + if (scan && scan != ((void *)1)) + { + size_t tmp_key; + size_t 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; + 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++; + } + } + _map_->flag = CMC_FLAG_OK; + return result; +} +_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_) +{ + _map1_->flag = CMC_FLAG_OK; + _map2_->flag = CMC_FLAG_OK; + if (_map1_->count != _map2_->count) + return 0; + struct hashbidimap *_mapA_; + struct hashbidimap *_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 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); + if (!entry_B) + return 0; + if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) + return 0; + } + } + return 1; +} +struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target) +{ + struct hashbidimap_iter *iter = target->alloc->malloc(sizeof(struct hashbidimap_iter)); + if (!iter) + return ((void *)0); + hbm_iter_init(iter, target); + return iter; +} +void hbm_iter_free(struct hashbidimap_iter *iter) +{ + iter->target->alloc->free(iter); +} +void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target) +{ + memset(iter, 0, sizeof(struct hashbidimap_iter)); + iter->target = target; + iter->start = 1; + iter->end = hbm_empty(target); + if (!hbm_empty(target)) + { + for (size_t i = 0; i < target->capacity; i++) + { + struct hashbidimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) + { + iter->first = i; + break; + } + } + iter->cursor = iter->first; + for (size_t i = target->capacity; i > 0; i--) + { + struct hashbidimap_entry *entry = target->buffer[i - 1][0]; + if (entry && entry != ((void *)1)) + { + iter->last = i - 1; + break; + } + } + } +} +_Bool hbm_iter_start(struct hashbidimap_iter *iter) +{ + return hbm_empty(iter->target) || iter->start; +} +_Bool hbm_iter_end(struct hashbidimap_iter *iter) +{ + return hbm_empty(iter->target) || iter->end; +} +void hbm_iter_to_start(struct hashbidimap_iter *iter) +{ + if (!hbm_empty(iter->target)) + { + iter->cursor = iter->first; + iter->index = 0; + iter->start = 1; + iter->end = 0; + } +} +void hbm_iter_to_end(struct hashbidimap_iter *iter) +{ + if (!hbm_empty(iter->target)) + { + iter->cursor = iter->last; + iter->index = iter->target->count - 1; + iter->start = 0; + iter->end = 1; + } +} +_Bool hbm_iter_next(struct hashbidimap_iter *iter) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = hbm_empty(iter->target); + struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; + iter->index++; + while (1) + { + iter->cursor++; + scan = iter->target->buffer[iter->cursor][0]; + if (scan != ((void *)0) && scan != ((void *)1)) + break; + } + return 1; +} +_Bool hbm_iter_prev(struct hashbidimap_iter *iter) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + iter->end = hbm_empty(iter->target); + struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; + iter->index--; + while (1) + { + iter->cursor--; + scan = iter->target->buffer[iter->cursor][0]; + if (scan != ((void *)0) && scan != ((void *)1)) + break; + } + return 1; +} +_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + for (size_t i = 0; i < steps; i++) + hbm_iter_next(iter); + return 1; +} +_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + for (size_t i = 0; i < steps; i++) + hbm_iter_prev(iter); + return 1; +} +_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return hbm_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return hbm_iter_advance(iter, index - iter->index); + return 1; +} +size_t hbm_iter_key(struct hashbidimap_iter *iter) +{ + if (hbm_empty(iter->target)) + { + iter->target->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + return iter->target->buffer[iter->cursor][0]->key; +} +size_t hbm_iter_value(struct hashbidimap_iter *iter) +{ + if (hbm_empty(iter->target)) + { + iter->target->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + return iter->target->buffer[iter->cursor][0]->value; +} +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) +{ + struct hashbidimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashbidimap_entry)); + if (!entry) + return ((void *)0); + entry->key = key; + entry->value = value; + entry->dist[0] = 0; + entry->dist[1] = 0; + entry->ref[0] = ((void *)0); + entry->ref[1] = ((void *)0); + return entry; +} +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; + struct hashbidimap_entry *target = _map_->buffer[pos][0]; + while (target != ((void *)0)) + { + if (target != ((void *)1) && _map_->f_key->cmp(target->key, key) == 0) + return &(_map_->buffer[pos % _map_->capacity][0]); + pos++; + target = _map_->buffer[pos % _map_->capacity][0]; + } + return ((void *)0); +} +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; + struct hashbidimap_entry *target = _map_->buffer[pos][1]; + while (target != ((void *)0)) + { + if (target != ((void *)1) && _map_->f_val->cmp(target->value, val) == 0) + return &(_map_->buffer[pos % _map_->capacity][1]); + pos++; + target = _map_->buffer[pos % _map_->capacity][1]; + } + return ((void *)0); +} +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]); + if (*scan == ((void *)0)) + { + *scan = entry; + entry->ref[0] = scan; + return scan; + } + else + { + while (1) + { + pos++; + scan = &(_map_->buffer[pos % _map_->capacity][0]); + if (*scan == ((void *)0) || *scan == ((void *)1)) + { + 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 hashbidimap_entry *_tmp_ = *scan; + *scan = entry; + entry = _tmp_; + } + } + } + return ((void *)0); +} +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]); + if (*scan == ((void *)0)) + { + *scan = entry; + entry->ref[1] = scan; + return scan; + } + else + { + while (1) + { + pos++; + scan = &(_map_->buffer[pos % _map_->capacity][1]); + if (*scan == ((void *)0) || *scan == ((void *)1)) + { + 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 hashbidimap_entry *_tmp_ = *scan; + *scan = entry; + entry = _tmp_; + } + } + } + return ((void *)0); +} +static size_t hbm_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 hashbidimap_iter hbm_impl_it_start(struct hashbidimap *_map_) +{ + struct hashbidimap_iter iter; + hbm_iter_init(&iter, _map_); + return iter; +} +static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_) +{ + struct hashbidimap_iter iter; + hbm_iter_init(&iter, _map_); + hbm_iter_to_end(&iter); + return iter; +} +_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr) +{ + struct hashbidimap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); +} +_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) +{ + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _map_->capacity; i > 0; i--) + { + struct hashbidimap_entry *entry = _map_->buffer[i - 1][0]; + if (entry && entry != ((void *)1)) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashbidimap_entry *entry = _map_->buffer[i][0]; + if (entry && entry != ((void *)1)) + { + if (!_map_->f_key->str(fptr, entry->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_hashmap.c b/tests/src/tst_cmc_hashmap.c index 19773cf..8135d58 100644 --- a/tests/src/tst_cmc_hashmap.c +++ b/tests/src/tst_cmc_hashmap.c @@ -1,7 +1,788 @@ - #include "tst_cmc_hashmap.h" +#include "tst_cmc_hashmap.h" - - 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) { 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) { ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); size_t real_capacity = hm_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; struct hashmap *_map_ = alloc->malloc(sizeof(struct hashmap)); if (!_map_) return ((void *)0); _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); if (!_map_->buffer) { alloc->free(_map_); return ((void *)0); } _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; (_map_)->callbacks = callbacks; return _map_; } void hm_clear(struct hashmap * _map_) { if (_map_->f_key->free || _map_->f_val->free) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashmap_entry *entry = &(_map_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (_map_->f_key->free) _map_->f_key->free(entry->key); if (_map_->f_val->free) _map_->f_val->free(entry->value); } } } memset(_map_->buffer, 0, sizeof(struct hashmap_entry) * _map_->capacity); _map_->count = 0; _map_->flag = CMC_FLAG_OK; } void hm_free(struct hashmap * _map_) { if (_map_->f_key->free || _map_->f_val->free) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashmap_entry *entry = &(_map_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (_map_->f_key->free) _map_->f_key->free(entry->key); if (_map_->f_val->free) _map_->f_val->free(entry->value); } } } _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } void hm_customize(struct hashmap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hm_insert(struct hashmap * _map_, size_t key, size_t value) { if (hm_full(_map_)) { if (!hm_resize(_map_, _map_->capacity + 1)) return 0; } if (hm_impl_get_entry(_map_, key) != ((void *)0)) { _map_->flag = CMC_FLAG_DUPLICATE; return 0; } size_t hash = _map_->f_key->hash(key); size_t original_pos = hash % _map_->capacity; size_t pos = original_pos; struct hashmap_entry *target = &(_map_->buffer[pos]); if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->key = key; target->value = value; target->dist = 0; target->state = CMC_ES_FILLED; } else { while (1) { 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) { size_t tmp_k = target->key; size_t 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 1; } _Bool hm_update(struct hashmap * _map_, size_t key, size_t new_value, size_t * old_value) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } 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 1; } _Bool hm_remove(struct hashmap * _map_, size_t key, size_t * out_value) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmap_entry *result = hm_impl_get_entry(_map_, key); if (result == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_value) *out_value = result->value; result->key = (size_t){ 0 }; result->value = (size_t){ 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 1; } _Bool hm_max(struct hashmap * _map_, size_t * key, size_t * value) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { if (first) { max_key = _map_->buffer[i].key; max_val = _map_->buffer[i].value; first = 0; } else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) { max_key = _map_->buffer[i].key; max_val = _map_->buffer[i].value; } } } if (key) *key = max_key; if (value) *value = max_val; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return 1; } _Bool hm_min(struct hashmap * _map_, size_t * key, size_t * value) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t min_key = (size_t){ 0 }; size_t min_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { if (first) { min_key = _map_->buffer[i].key; min_val = _map_->buffer[i].value; first = 0; } else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) { min_key = _map_->buffer[i].key; min_val = _map_->buffer[i].value; } } } if (key) *key = min_key; if (value) *value = min_val; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return 1; } size_t hm_get(struct hashmap * _map_, size_t key) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return entry->value; } size_t *hm_get_ref(struct hashmap * _map_, size_t key) { if (hm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return ((void *)0); } struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return &(entry->value); } _Bool hm_contains(struct hashmap * _map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hm_impl_get_entry(_map_, key) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool hm_empty(struct hashmap * _map_) { return _map_->count == 0; } _Bool hm_full(struct hashmap * _map_) { return (double)_map_->capacity * _map_->load <= (double)_map_->count; } size_t hm_count(struct hashmap * _map_) { return _map_->count; } size_t hm_capacity(struct hashmap * _map_) { return _map_->capacity; } double hm_load(struct hashmap * _map_) { return _map_->load; } int hm_flag(struct hashmap * _map_) { return _map_->flag; } _Bool hm_resize(struct hashmap * _map_, size_t capacity) { _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hm_impl_calculate_size(capacity); if (theoretical_size < _map_->count / _map_->load) { _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashmap *_new_map_ = hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { size_t key = _map_->buffer[i].key; size_t value = _map_->buffer[i].value; hm_insert(_new_map_, key, value); } } if (_map_->count != _new_map_->count) { hm_free(_new_map_); _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashmap_entry *tmp_b = _map_->buffer; _map_->buffer = _new_map_->buffer; _new_map_->buffer = tmp_b; size_t tmp_c = _map_->capacity; _map_->capacity = _new_map_->capacity; _new_map_->capacity = tmp_c; _new_map_->f_key = &(struct hashmap_fkey){ ((void *)0) }; _new_map_->f_val = &(struct hashmap_fval){ ((void *)0) }; hm_free(_new_map_); success: if ((_map_)->callbacks && (_map_)->callbacks->resize) (_map_)->callbacks->resize();; return 1; } struct hashmap *hm_copy_of(struct hashmap * _map_) { struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _map_->callbacks; if (_map_->f_key->cpy || _map_->f_val->cpy) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashmap_entry *scan = &(_map_->buffer[i]); if (scan->state != CMC_ES_EMPTY) { struct hashmap_entry *target = &(result->buffer[i]); if (scan->state == CMC_ES_DELETED) target->state = CMC_ES_DELETED; else { target->state = scan->state; target->dist = scan->dist; if (_map_->f_key->cpy) target->key = _map_->f_key->cpy(scan->key); else target->key = scan->key; if (_map_->f_val->cpy) target->value = _map_->f_val->cpy(scan->value); else target->value = scan->value; } } } } else memcpy(result->buffer, _map_->buffer, sizeof(struct hashmap_entry) * _map_->capacity); result->count = _map_->count; _map_->flag = CMC_FLAG_OK; return result; } _Bool hm_equals(struct hashmap * _map1_, struct hashmap * _map2_) { _map1_->flag = CMC_FLAG_OK; _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashmap *_map_a_; struct hashmap *_map_b_; _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; for (size_t i = 0; i < _map_a_->capacity; i++) { if (_map_a_->buffer[i].state == CMC_ES_FILLED) { struct hashmap_entry *entry_a = &(_map_a_->buffer[i]); struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key); if (!entry_b) return 0; if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) return 0; } } return 1; } static struct hashmap_entry * hm_impl_get_entry(struct hashmap * _map_, size_t key) { size_t hash = _map_->f_key->hash(key); size_t pos = hash % _map_->capacity; struct hashmap_entry *target = &(_map_->buffer[pos]); while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) { if (_map_->f_key->cmp(target->key, key) == 0) return target; pos++; target = &(_map_->buffer[pos % _map_->capacity]); } return ((void *)0); } static size_t hm_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; while (cmc_hashtable_primes[i] < required) i++; return cmc_hashtable_primes[i]; } struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val) { return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey * f_key, struct hashmap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; struct hashmap _map_ = { 0 }; if (capacity == 0 || load <= 0 || load >= 1) return _map_; if (capacity >= 0xffffffffffffffffULL * load) return _map_; if (!f_key || !f_val) return _map_; size_t real_capacity = hm_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); if (!_map_.buffer) return _map_; _map_.count = 0; _map_.capacity = real_capacity; _map_.load = load; _map_.flag = CMC_FLAG_OK; _map_.f_key = f_key; _map_.f_val = f_val; _map_.alloc = alloc; (&_map_)->callbacks = callbacks; return _map_; } void hm_release(struct hashmap _map_) { if (_map_.f_key->free || _map_.f_val->free) { for (size_t i = 0; i < _map_.capacity; i++) { struct hashmap_entry *entry = &(_map_.buffer[i]); if (entry->state == CMC_ES_FILLED) { if (_map_.f_key->free) _map_.f_key->free(entry->key); if (_map_.f_val->free) _map_.f_val->free(entry->value); } } } _map_.alloc->free(_map_.buffer); } struct hashmap_iter hm_iter_start(struct hashmap * target) { struct hashmap_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = 1; iter.end = hm_empty(target); if (!hm_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 hashmap_iter hm_iter_end(struct hashmap * target) { struct hashmap_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = hm_empty(target); iter.end = 1; if (!hm_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 hm_iter_at_start(struct hashmap_iter * iter) { return hm_empty(iter->target) || iter->start; } _Bool hm_iter_at_end(struct hashmap_iter * iter) { return hm_empty(iter->target) || iter->end; } _Bool hm_iter_to_start(struct hashmap_iter * iter) { if (!hm_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = hm_empty(iter->target); return 1; } return 0; } _Bool hm_iter_to_end(struct hashmap_iter * iter) { if (!hm_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = hm_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool hm_iter_next(struct hashmap_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = hm_empty(iter->target); struct hashmap_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index++; while (1) { iter->cursor++; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hm_iter_prev(struct hashmap_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = hm_empty(iter->target); struct hashmap_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index--; while (1) { iter->cursor--; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hm_iter_advance(struct hashmap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hm_iter_next(iter); return 1; } _Bool hm_iter_rewind(struct hashmap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hm_iter_prev(iter); return 1; } _Bool hm_iter_go_to(struct hashmap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hm_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hm_iter_advance(iter, index - iter->index); return 1; } size_t hm_iter_key(struct hashmap_iter * iter) { if (hm_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor].key; } size_t hm_iter_value(struct hashmap_iter * iter) { if (hm_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor].value; } size_t *hm_iter_rvalue(struct hashmap_iter * iter) { if (hm_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor].value); } size_t hm_iter_index(struct hashmap_iter * iter) { return iter->index; } _Bool hm_to_string(struct hashmap * _map_, FILE * fptr) { struct hashmap *m_ = _map_; return 0 <= fprintf(fptr, "struct %s<%s, %s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_key:%p, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } _Bool hm_print(struct hashmap * _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 hashmap_entry *entry = &(_map_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (!_map_->f_key->str(fptr, entry->key)) return 0; fprintf(fptr, "%s", key_val_sep); if (!_map_->f_val->str(fptr, entry->value)) return 0; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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) +{ + 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) +{ + ; + if (capacity == 0 || load <= 0 || load >= 1) + return ((void *)0); + if (capacity >= 0xffffffffffffffffULL * load) + return ((void *)0); + if (!f_key || !f_val) + return ((void *)0); + size_t real_capacity = hm_impl_calculate_size(capacity / load); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct hashmap *_map_ = alloc->malloc(sizeof(struct hashmap)); + if (!_map_) + return ((void *)0); + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); + if (!_map_->buffer) + { + alloc->free(_map_); + return ((void *)0); + } + _map_->count = 0; + _map_->capacity = real_capacity; + _map_->load = load; + _map_->flag = CMC_FLAG_OK; + _map_->f_key = f_key; + _map_->f_val = f_val; + _map_->alloc = alloc; + (_map_)->callbacks = callbacks; + return _map_; +} +void hm_clear(struct hashmap *_map_) +{ + if (_map_->f_key->free || _map_->f_val->free) + { + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmap_entry *entry = &(_map_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (_map_->f_key->free) + _map_->f_key->free(entry->key); + if (_map_->f_val->free) + _map_->f_val->free(entry->value); + } + } + } + memset(_map_->buffer, 0, sizeof(struct hashmap_entry) * _map_->capacity); + _map_->count = 0; + _map_->flag = CMC_FLAG_OK; +} +void hm_free(struct hashmap *_map_) +{ + if (_map_->f_key->free || _map_->f_val->free) + { + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmap_entry *entry = &(_map_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (_map_->f_key->free) + _map_->f_key->free(entry->key); + if (_map_->f_val->free) + _map_->f_val->free(entry->value); + } + } + } + _map_->alloc->free(_map_->buffer); + _map_->alloc->free(_map_); +} +void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _map_->alloc = &cmc_alloc_node_default; + else + _map_->alloc = alloc; + (_map_)->callbacks = callbacks; + _map_->flag = CMC_FLAG_OK; +} +_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) +{ + if (hm_full(_map_)) + { + if (!hm_resize(_map_, _map_->capacity + 1)) + return 0; + } + if (hm_impl_get_entry(_map_, key) != ((void *)0)) + { + _map_->flag = CMC_FLAG_DUPLICATE; + return 0; + } + size_t hash = _map_->f_key->hash(key); + size_t original_pos = hash % _map_->capacity; + size_t pos = original_pos; + struct hashmap_entry *target = &(_map_->buffer[pos]); + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) + { + target->key = key; + target->value = value; + target->dist = 0; + target->state = CMC_ES_FILLED; + } + else + { + while (1) + { + 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) + { + size_t tmp_k = target->key; + size_t 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 1; +} +_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value) +{ + if (hm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); + if (!entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + 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 1; +} +_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) +{ + if (hm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashmap_entry *result = hm_impl_get_entry(_map_, key); + if (result == ((void *)0)) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + if (out_value) + *out_value = result->value; + result->key = (size_t){ 0 }; + result->value = (size_t){ 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 1; +} +_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) +{ + if (hm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + _Bool first = 1; + size_t max_key = (size_t){ 0 }; + size_t max_val = (size_t){ 0 }; + for (size_t i = 0; i < _map_->capacity; i++) + { + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + max_key = _map_->buffer[i].key; + max_val = _map_->buffer[i].value; + first = 0; + } + else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) + { + max_key = _map_->buffer[i].key; + max_val = _map_->buffer[i].value; + } + } + } + if (key) + *key = max_key; + if (value) + *value = max_val; + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return 1; +} +_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) +{ + if (hm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + _Bool first = 1; + size_t min_key = (size_t){ 0 }; + size_t min_val = (size_t){ 0 }; + for (size_t i = 0; i < _map_->capacity; i++) + { + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + min_key = _map_->buffer[i].key; + min_val = _map_->buffer[i].value; + first = 0; + } + else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) + { + min_key = _map_->buffer[i].key; + min_val = _map_->buffer[i].value; + } + } + } + if (key) + *key = min_key; + if (value) + *value = min_val; + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return 1; +} +size_t hm_get(struct hashmap *_map_, size_t key) +{ + if (hm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); + if (!entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return (size_t){ 0 }; + } + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return entry->value; +} +size_t *hm_get_ref(struct hashmap *_map_, size_t key) +{ + if (hm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return ((void *)0); + } + struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); + if (!entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return ((void *)0); + } + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return &(entry->value); +} +_Bool hm_contains(struct hashmap *_map_, size_t key) +{ + _map_->flag = CMC_FLAG_OK; + _Bool result = hm_impl_get_entry(_map_, key) != ((void *)0); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return result; +} +_Bool hm_empty(struct hashmap *_map_) +{ + return _map_->count == 0; +} +_Bool hm_full(struct hashmap *_map_) +{ + return (double)_map_->capacity * _map_->load <= (double)_map_->count; +} +size_t hm_count(struct hashmap *_map_) +{ + return _map_->count; +} +size_t hm_capacity(struct hashmap *_map_) +{ + return _map_->capacity; +} +double hm_load(struct hashmap *_map_) +{ + return _map_->load; +} +int hm_flag(struct hashmap *_map_) +{ + return _map_->flag; +} +_Bool hm_resize(struct hashmap *_map_, size_t capacity) +{ + _map_->flag = CMC_FLAG_OK; + if (_map_->capacity == capacity) + goto success; + if (_map_->capacity > capacity / _map_->load) + goto success; + if (capacity >= 0xffffffffffffffffULL * _map_->load) + { + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + size_t theoretical_size = hm_impl_calculate_size(capacity); + if (theoretical_size < _map_->count / _map_->load) + { + _map_->flag = CMC_FLAG_INVALID; + return 0; + } + struct hashmap *_new_map_ = + hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); + if (!_new_map_) + { + _map_->flag = CMC_FLAG_ALLOC; + return 0; + } + for (size_t i = 0; i < _map_->capacity; i++) + { + if (_map_->buffer[i].state == CMC_ES_FILLED) + { + size_t key = _map_->buffer[i].key; + size_t value = _map_->buffer[i].value; + hm_insert(_new_map_, key, value); + } + } + if (_map_->count != _new_map_->count) + { + hm_free(_new_map_); + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + struct hashmap_entry *tmp_b = _map_->buffer; + _map_->buffer = _new_map_->buffer; + _new_map_->buffer = tmp_b; + size_t tmp_c = _map_->capacity; + _map_->capacity = _new_map_->capacity; + _new_map_->capacity = tmp_c; + _new_map_->f_key = &(struct hashmap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct hashmap_fval){ ((void *)0) }; + hm_free(_new_map_); +success: + if ((_map_)->callbacks && (_map_)->callbacks->resize) + (_map_)->callbacks->resize(); + ; + return 1; +} +struct hashmap *hm_copy_of(struct hashmap *_map_) +{ + struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, + _map_->alloc, ((void *)0)); + if (!result) + { + _map_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _map_->callbacks; + if (_map_->f_key->cpy || _map_->f_val->cpy) + { + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmap_entry *scan = &(_map_->buffer[i]); + if (scan->state != CMC_ES_EMPTY) + { + struct hashmap_entry *target = &(result->buffer[i]); + if (scan->state == CMC_ES_DELETED) + target->state = CMC_ES_DELETED; + else + { + target->state = scan->state; + target->dist = scan->dist; + if (_map_->f_key->cpy) + target->key = _map_->f_key->cpy(scan->key); + else + target->key = scan->key; + if (_map_->f_val->cpy) + target->value = _map_->f_val->cpy(scan->value); + else + target->value = scan->value; + } + } + } + } + else + memcpy(result->buffer, _map_->buffer, sizeof(struct hashmap_entry) * _map_->capacity); + result->count = _map_->count; + _map_->flag = CMC_FLAG_OK; + return result; +} +_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_) +{ + _map1_->flag = CMC_FLAG_OK; + _map2_->flag = CMC_FLAG_OK; + if (_map1_->count != _map2_->count) + return 0; + struct hashmap *_map_a_; + struct hashmap *_map_b_; + _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; + _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; + for (size_t i = 0; i < _map_a_->capacity; i++) + { + if (_map_a_->buffer[i].state == CMC_ES_FILLED) + { + struct hashmap_entry *entry_a = &(_map_a_->buffer[i]); + struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key); + if (!entry_b) + return 0; + if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) + return 0; + } + } + return 1; +} +static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + size_t pos = hash % _map_->capacity; + struct hashmap_entry *target = &(_map_->buffer[pos]); + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) + { + if (_map_->f_key->cmp(target->key, key) == 0) + return target; + pos++; + target = &(_map_->buffer[pos % _map_->capacity]); + } + return ((void *)0); +} +static size_t hm_impl_calculate_size(size_t required) +{ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; +} +struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) +{ + return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); +} +struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + struct hashmap _map_ = { 0 }; + if (capacity == 0 || load <= 0 || load >= 1) + return _map_; + if (capacity >= 0xffffffffffffffffULL * load) + return _map_; + if (!f_key || !f_val) + return _map_; + size_t real_capacity = hm_impl_calculate_size(capacity / load); + if (!alloc) + alloc = &cmc_alloc_node_default; + _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); + if (!_map_.buffer) + return _map_; + _map_.count = 0; + _map_.capacity = real_capacity; + _map_.load = load; + _map_.flag = CMC_FLAG_OK; + _map_.f_key = f_key; + _map_.f_val = f_val; + _map_.alloc = alloc; + (&_map_)->callbacks = callbacks; + return _map_; +} +void hm_release(struct hashmap _map_) +{ + if (_map_.f_key->free || _map_.f_val->free) + { + for (size_t i = 0; i < _map_.capacity; i++) + { + struct hashmap_entry *entry = &(_map_.buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (_map_.f_key->free) + _map_.f_key->free(entry->key); + if (_map_.f_val->free) + _map_.f_val->free(entry->value); + } + } + } + _map_.alloc->free(_map_.buffer); +} +struct hashmap_iter hm_iter_start(struct hashmap *target) +{ + struct hashmap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.index = 0; + iter.first = 0; + iter.last = 0; + iter.start = 1; + iter.end = hm_empty(target); + if (!hm_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 hashmap_iter hm_iter_end(struct hashmap *target) +{ + struct hashmap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.index = 0; + iter.first = 0; + iter.last = 0; + iter.start = hm_empty(target); + iter.end = 1; + if (!hm_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 hm_iter_at_start(struct hashmap_iter *iter) +{ + return hm_empty(iter->target) || iter->start; +} +_Bool hm_iter_at_end(struct hashmap_iter *iter) +{ + return hm_empty(iter->target) || iter->end; +} +_Bool hm_iter_to_start(struct hashmap_iter *iter) +{ + if (!hm_empty(iter->target)) + { + iter->cursor = iter->first; + iter->index = 0; + iter->start = 1; + iter->end = hm_empty(iter->target); + return 1; + } + return 0; +} +_Bool hm_iter_to_end(struct hashmap_iter *iter) +{ + if (!hm_empty(iter->target)) + { + iter->cursor = iter->last; + iter->index = iter->target->count - 1; + iter->start = hm_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool hm_iter_next(struct hashmap_iter *iter) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = hm_empty(iter->target); + struct hashmap_entry *scan = &(iter->target->buffer[iter->cursor]); + iter->index++; + while (1) + { + iter->cursor++; + scan = &(iter->target->buffer[iter->cursor]); + if (scan->state == CMC_ES_FILLED) + break; + } + return 1; +} +_Bool hm_iter_prev(struct hashmap_iter *iter) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + iter->end = hm_empty(iter->target); + struct hashmap_entry *scan = &(iter->target->buffer[iter->cursor]); + iter->index--; + while (1) + { + iter->cursor--; + scan = &(iter->target->buffer[iter->cursor]); + if (scan->state == CMC_ES_FILLED) + break; + } + return 1; +} +_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + for (size_t i = 0; i < steps; i++) + hm_iter_next(iter); + return 1; +} +_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + for (size_t i = 0; i < steps; i++) + hm_iter_prev(iter); + return 1; +} +_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return hm_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return hm_iter_advance(iter, index - iter->index); + return 1; +} +size_t hm_iter_key(struct hashmap_iter *iter) +{ + if (hm_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor].key; +} +size_t hm_iter_value(struct hashmap_iter *iter) +{ + if (hm_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor].value; +} +size_t *hm_iter_rvalue(struct hashmap_iter *iter) +{ + if (hm_empty(iter->target)) + return ((void *)0); + return &(iter->target->buffer[iter->cursor].value); +} +size_t hm_iter_index(struct hashmap_iter *iter) +{ + return iter->index; +} +_Bool hm_to_string(struct hashmap *_map_, FILE *fptr) +{ + struct hashmap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); +} +_Bool hm_print(struct hashmap *_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 hashmap_entry *entry = &(_map_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_map_->f_key->str(fptr, entry->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_hashmultimap.c b/tests/src/tst_cmc_hashmultimap.c index fa8d7c1..79177d4 100644 --- a/tests/src/tst_cmc_hashmultimap.c +++ b/tests/src/tst_cmc_hashmultimap.c @@ -1,7 +1,931 @@ - #include "tst_cmc_hashmultimap.h" +#include "tst_cmc_hashmultimap.h" - - 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_fval * f_val) { return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); } struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey * f_key, struct hashmultimap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || load <= 0) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_key || !f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; size_t real_capacity = hmm_impl_calculate_size(capacity / load); struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); if (!_map_) return ((void *)0); _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); if (!_map_->buffer) { alloc->free(_map_); return ((void *)0); } _map_->count = 0; _map_->capacity = real_capacity; _map_->load = load; _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; (_map_)->callbacks = callbacks; return _map_; } void hmm_clear(struct hashmultimap * _map_) { for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { struct hashmultimap_entry *next = scan->next; if (_map_->f_key->free) _map_->f_key->free(scan->key); if (_map_->f_val->free) _map_->f_val->free(scan->value); _map_->alloc->free(scan); scan = next; } } memset(_map_->buffer, 0, sizeof(struct hashmultimap_entry *[2]) * _map_->capacity); _map_->count = 0; _map_->flag = CMC_FLAG_OK; } void hmm_free(struct hashmultimap * _map_) { size_t index = 0; while (index < _map_->capacity) { struct hashmultimap_entry *scan = _map_->buffer[index][0]; if (scan) { if (scan->next == ((void *)0) && scan->prev == ((void *)0)) { 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) { struct hashmultimap_entry *tmp = scan; scan = scan->next; if (_map_->f_key->free) _map_->f_key->free(tmp->key); if (_map_->f_val->free) _map_->f_val->free(tmp->value); _map_->alloc->free(tmp); } } } index++; } _map_->alloc->free(_map_->buffer); _map_->alloc->free(_map_); } void hmm_customize(struct hashmultimap * _map_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool hmm_insert(struct hashmultimap * _map_, size_t key, size_t value) { if (hmm_full(_map_)) { if (!hmm_resize(_map_, _map_->capacity + 1)) return 0; } size_t hash = _map_->f_key->hash(key); size_t pos = hash % _map_->capacity; struct hashmultimap_entry *entry = hmm_impl_new_entry(_map_, key, value); if (_map_->buffer[pos][0] == ((void *)0)) { _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 1; } _Bool hmm_update(struct hashmultimap * _map_, size_t key, size_t new_value, size_t * old_value) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } 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 1; } size_t hmm_update_all(struct hashmultimap * _map_, size_t key, size_t new_value, size_t * *old_values) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; if (entry == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (old_values) { size_t total = hmm_impl_key_count(_map_, key); if (total == 0) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } *old_values = _map_->alloc->malloc(sizeof(size_t) * total); if (!(*old_values)) { _map_->flag = CMC_FLAG_ALLOC; return 0; } } size_t index = 0; while (entry) { 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 hmm_remove(struct hashmultimap * _map_, size_t key, size_t * out_value) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; 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]); if (*head == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } struct hashmultimap_entry *entry = *head; if (entry->next == ((void *)0) && entry->prev == ((void *)0)) { if (_map_->f_key->cmp(entry->key, key) == 0) { *head = ((void *)0); *tail = ((void *)0); if (out_value) *out_value = entry->value; } else { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } } else { _Bool found = 0; while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) { if (*head == entry) *head = entry->next; if (*tail == entry) *tail = entry->prev; if (entry->prev) entry->prev->next = entry->next; if (entry->next) entry->next->prev = entry->prev; if (out_value) *out_value = entry->value; found = 1; break; } else entry = entry->next; } if (!found) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } } _map_->alloc->free(entry); _map_->count--; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->delete) (_map_)->callbacks->delete();; return 1; } size_t hmm_remove_all(struct hashmultimap * _map_, size_t key, size_t * *out_values) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; 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]); if (*head == ((void *)0)) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_values) { size_t total = hmm_impl_key_count(_map_, key); if (total == 0) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } *out_values = _map_->alloc->malloc(sizeof(size_t) * total); if (!(*out_values)) { _map_->flag = CMC_FLAG_ALLOC; return 0; } } size_t index = 0; struct hashmultimap_entry *entry = *head; if (entry->next == ((void *)0)) { *head = ((void *)0); *tail = ((void *)0); if (out_values) (*out_values)[index] = entry->value; index++; _map_->alloc->free(entry); } else { while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) { if (*head == entry) *head = entry->next; if (*tail == entry) *tail = entry->prev; struct hashmultimap_entry *next = entry->next; if (entry->prev) entry->prev->next = entry->next; if (entry->next) 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 hmm_max(struct hashmultimap * _map_, size_t * key, size_t * value) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { if (first) { max_key = scan->key; max_val = scan->value; first = 0; } else if (_map_->f_key->cmp(scan->key, max_key) > 0) { max_key = scan->key; max_val = scan->value; } scan = scan->next; } } 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 1; } _Bool hmm_min(struct hashmultimap * _map_, size_t * key, size_t * value) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t min_key = (size_t){ 0 }; size_t min_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { if (first) { min_key = scan->key; min_val = scan->value; first = 0; } else if (_map_->f_key->cmp(scan->key, min_key) < 0) { min_key = scan->key; min_val = scan->value; } scan = scan->next; } } 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 1; } size_t hmm_get(struct hashmultimap * _map_, size_t key) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return entry->value; } size_t *hmm_get_ref(struct hashmultimap * _map_, size_t key) { if (hmm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return ((void *)0); } struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); if (!entry) { _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return &(entry->value); } _Bool hmm_contains(struct hashmultimap * _map_, size_t key) { _map_->flag = CMC_FLAG_OK; _Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool hmm_empty(struct hashmultimap * _map_) { return _map_->count == 0; } _Bool hmm_full(struct hashmultimap * _map_) { return (double)_map_->capacity * _map_->load <= (double)_map_->count; } size_t hmm_count(struct hashmultimap * _map_) { return _map_->count; } size_t hmm_key_count(struct hashmultimap * _map_, size_t key) { return hmm_impl_key_count(_map_, key); } size_t hmm_capacity(struct hashmultimap * _map_) { return _map_->capacity; } double hmm_load(struct hashmultimap * _map_) { return _map_->load; } int hmm_flag(struct hashmultimap * _map_) { return _map_->flag; } _Bool hmm_resize(struct hashmultimap * _map_, size_t capacity) { _map_->flag = CMC_FLAG_OK; if (_map_->capacity == capacity) goto success; if (_map_->capacity > capacity / _map_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _map_->load) { _map_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hmm_impl_calculate_size(capacity); if (theoretical_size < _map_->count / _map_->load) { _map_->flag = CMC_FLAG_INVALID; return 0; } struct hashmultimap *_new_map_ = hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!_new_map_) { _map_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { hmm_insert(_new_map_, scan->key, scan->value); scan = scan->next; } } if (_map_->count != _new_map_->count) { hmm_free(_new_map_); _map_->flag = CMC_FLAG_ERROR; return 0; } struct hashmultimap_entry * (*tmp_b)[2] = _map_->buffer; _map_->buffer = _new_map_->buffer; _new_map_->buffer = tmp_b; size_t tmp_c = _map_->capacity; _map_->capacity = _new_map_->capacity; _new_map_->capacity = tmp_c; _new_map_->f_key = &(struct hashmultimap_fkey){ ((void *)0) }; _new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) }; hmm_free(_new_map_); success: if ((_map_)->callbacks && (_map_)->callbacks->resize) (_map_)->callbacks->resize();; return 1; } 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)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan) { size_t key; size_t value; if (_map_->f_key->cpy) key = _map_->f_key->cpy(scan->key); else key = scan->key; if (_map_->f_val->cpy) value = _map_->f_val->cpy(scan->value); else value = scan->value; hmm_insert(result, key, value); scan = scan->next; } } (result)->callbacks = _map_->callbacks; _map_->flag = CMC_FLAG_OK; return result; } _Bool hmm_equals(struct hashmultimap * _map1_, struct hashmultimap * _map2_) { _map1_->flag = CMC_FLAG_OK; _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct hashmultimap *_map_a_; struct hashmultimap *_map_b_; _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; for (size_t i = 0; i < _map_a_->capacity; i++) { struct hashmultimap_entry *scan = _map_a_->buffer[i][0]; while (scan) { if (hmm_impl_key_count(_map_a_, scan->key) != hmm_impl_key_count(_map_b_, scan->key)) return 0; scan = scan->next; } } return 1; } struct hashmultimap_entry * hmm_impl_new_entry(struct hashmultimap * _map_, size_t key, size_t value) { struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); if (!entry) return ((void *)0); entry->key = key; entry->value = value; entry->next = ((void *)0); entry->prev = ((void *)0); return entry; } struct hashmultimap_entry * hmm_impl_get_entry(struct hashmultimap * _map_, size_t key) { size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) return entry; entry = entry->next; } return ((void *)0); } size_t hmm_impl_key_count(struct hashmultimap * _map_, size_t key) { size_t hash = _map_->f_key->hash(key); struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; size_t total_count = 0; if (!entry) return total_count; while (entry) { if (_map_->f_key->cmp(entry->key, key) == 0) total_count++; entry = entry->next; } return total_count; } size_t hmm_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; while (cmc_hashtable_primes[i] < required) i++; return cmc_hashtable_primes[i]; } struct hashmultimap_iter hmm_iter_start(struct hashmultimap * target) { struct hashmultimap_iter iter; iter.target = target; iter.curr_entry = ((void *)0); iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = 1; iter.end = hmm_empty(target); if (!hmm_empty(target)) { for (size_t i = 0; i < target->capacity; i++) { struct hashmultimap_entry *entry = target->buffer[i][0]; if (entry && entry != ((void *)1)) { 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 hashmultimap_entry *entry = target->buffer[i - 1][1]; if (entry && entry != ((void *)1)) { iter.last = i - 1; break; } } } return iter; } struct hashmultimap_iter hmm_iter_end(struct hashmultimap * target) { struct hashmultimap_iter iter; iter.target = target; iter.curr_entry = ((void *)0); iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = hmm_empty(target); iter.end = 1; if (!hmm_empty(target)) { for (size_t i = 0; i < target->capacity; i++) { struct hashmultimap_entry *entry = target->buffer[i][0]; if (entry && entry != ((void *)1)) { iter.first = i; break; } } for (size_t i = target->capacity; i > 0; i--) { struct hashmultimap_entry *entry = target->buffer[i - 1][1]; if (entry && entry != ((void *)1)) { iter.curr_entry = target->buffer[i - 1][1]; iter.last = i - 1; break; } } iter.cursor = iter.last; iter.index = target->count - 1; } return iter; } _Bool hmm_iter_at_start(struct hashmultimap_iter * iter) { return hmm_empty(iter->target) || iter->start; } _Bool hmm_iter_at_end(struct hashmultimap_iter * iter) { return hmm_empty(iter->target) || iter->end; } _Bool hmm_iter_to_start(struct hashmultimap_iter * iter) { if (!hmm_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = hmm_empty(iter->target); iter->curr_entry = iter->target->buffer[iter->first][0]; return 1; } return 0; } _Bool hmm_iter_to_end(struct hashmultimap_iter * iter) { if (!hmm_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = hmm_empty(iter->target); iter->end = 1; iter->curr_entry = iter->target->buffer[iter->last][1]; return 1; } return 0; } _Bool hmm_iter_next(struct hashmultimap_iter * iter) { if (iter->end) return 0; if (iter->curr_entry->next != ((void *)0)) { iter->curr_entry = iter->curr_entry->next; iter->index++; } else { if (iter->cursor == iter->last) { iter->end = 1; return 0; } iter->cursor++; while (iter->target->buffer[iter->cursor][0] == ((void *)0)) iter->cursor++; iter->curr_entry = iter->target->buffer[iter->cursor][0]; iter->index++; } iter->start = hmm_empty(iter->target); return 1; } _Bool hmm_iter_prev(struct hashmultimap_iter * iter) { if (iter->start) return 0; if (iter->curr_entry->prev != ((void *)0)) { iter->curr_entry = iter->curr_entry->prev; iter->index--; } else { if (iter->cursor == iter->first) { iter->start = 1; return 0; } iter->cursor--; while (iter->target->buffer[iter->cursor][1] == ((void *)0)) iter->cursor--; iter->curr_entry = iter->target->buffer[iter->cursor][1]; iter->index--; } iter->end = hmm_empty(iter->target); return 1; } _Bool hmm_iter_advance(struct hashmultimap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hmm_iter_next(iter); return 1; } _Bool hmm_iter_rewind(struct hashmultimap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hmm_iter_prev(iter); return 1; } _Bool hmm_iter_go_to(struct hashmultimap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hmm_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hmm_iter_advance(iter, index - iter->index); return 1; } size_t hmm_iter_key(struct hashmultimap_iter * iter) { if (hmm_empty(iter->target)) return (size_t){ 0 }; return iter->curr_entry->key; } size_t hmm_iter_value(struct hashmultimap_iter * iter) { if (hmm_empty(iter->target)) return (size_t){ 0 }; return iter->curr_entry->value; } size_t *hmm_iter_rvalue(struct hashmultimap_iter * iter) { if (hmm_empty(iter->target)) return ((void *)0); return &(iter->curr_entry->value); } size_t hmm_iter_index(struct hashmultimap_iter * iter) { return iter->index; } _Bool hmm_to_string(struct hashmultimap * _map_, FILE * fptr) { struct hashmultimap *m_ = _map_; return 0 <= fprintf(fptr, "struct %s<%s, %s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_key:%p, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } _Bool hmm_print(struct hashmultimap * _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 hashmultimap_entry *entry = _map_->buffer[i - 1][1]; if (entry && entry != ((void *)1)) { last = i - 1; break; } } for (size_t i = 0; i < _map_->capacity; i++) { struct hashmultimap_entry *scan = _map_->buffer[i][0]; while (scan != ((void *)0)) { if (!_map_->f_key->str(fptr, scan->key)) return 0; fprintf(fptr, "%s", key_val_sep); if (!_map_->f_val->str(fptr, scan->value)) return 0; scan = scan->next; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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_fval *f_val) +{ + return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); +} +struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, + struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (capacity == 0 || load <= 0) + return ((void *)0); + if (capacity >= 0xffffffffffffffffULL * load) + return ((void *)0); + if (!f_key || !f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + size_t real_capacity = hmm_impl_calculate_size(capacity / load); + struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); + if (!_map_) + return ((void *)0); + _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); + if (!_map_->buffer) + { + alloc->free(_map_); + return ((void *)0); + } + _map_->count = 0; + _map_->capacity = real_capacity; + _map_->load = load; + _map_->flag = CMC_FLAG_OK; + _map_->f_key = f_key; + _map_->f_val = f_val; + _map_->alloc = alloc; + (_map_)->callbacks = callbacks; + return _map_; +} +void hmm_clear(struct hashmultimap *_map_) +{ + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) + { + struct hashmultimap_entry *next = scan->next; + if (_map_->f_key->free) + _map_->f_key->free(scan->key); + if (_map_->f_val->free) + _map_->f_val->free(scan->value); + _map_->alloc->free(scan); + scan = next; + } + } + memset(_map_->buffer, 0, sizeof(struct hashmultimap_entry *[2]) * _map_->capacity); + _map_->count = 0; + _map_->flag = CMC_FLAG_OK; +} +void hmm_free(struct hashmultimap *_map_) +{ + size_t index = 0; + while (index < _map_->capacity) + { + struct hashmultimap_entry *scan = _map_->buffer[index][0]; + if (scan) + { + if (scan->next == ((void *)0) && scan->prev == ((void *)0)) + { + 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) + { + struct hashmultimap_entry *tmp = scan; + scan = scan->next; + if (_map_->f_key->free) + _map_->f_key->free(tmp->key); + if (_map_->f_val->free) + _map_->f_val->free(tmp->value); + _map_->alloc->free(tmp); + } + } + } + index++; + } + _map_->alloc->free(_map_->buffer); + _map_->alloc->free(_map_); +} +void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _map_->alloc = &cmc_alloc_node_default; + else + _map_->alloc = alloc; + (_map_)->callbacks = callbacks; + _map_->flag = CMC_FLAG_OK; +} +_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) +{ + if (hmm_full(_map_)) + { + if (!hmm_resize(_map_, _map_->capacity + 1)) + return 0; + } + size_t hash = _map_->f_key->hash(key); + size_t pos = hash % _map_->capacity; + struct hashmultimap_entry *entry = hmm_impl_new_entry(_map_, key, value); + if (_map_->buffer[pos][0] == ((void *)0)) + { + _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 1; +} +_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value) +{ + if (hmm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); + if (!entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + 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 1; +} +size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values) +{ + if (hmm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + size_t hash = _map_->f_key->hash(key); + struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; + if (entry == ((void *)0)) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + if (old_values) + { + size_t total = hmm_impl_key_count(_map_, key); + if (total == 0) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + *old_values = _map_->alloc->malloc(sizeof(size_t) * total); + if (!(*old_values)) + { + _map_->flag = CMC_FLAG_ALLOC; + return 0; + } + } + size_t index = 0; + while (entry) + { + 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 hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) +{ + if (hmm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + 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]); + if (*head == ((void *)0)) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + struct hashmultimap_entry *entry = *head; + if (entry->next == ((void *)0) && entry->prev == ((void *)0)) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + { + *head = ((void *)0); + *tail = ((void *)0); + if (out_value) + *out_value = entry->value; + } + else + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + } + else + { + _Bool found = 0; + while (entry) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + { + if (*head == entry) + *head = entry->next; + if (*tail == entry) + *tail = entry->prev; + if (entry->prev) + entry->prev->next = entry->next; + if (entry->next) + entry->next->prev = entry->prev; + if (out_value) + *out_value = entry->value; + found = 1; + break; + } + else + entry = entry->next; + } + if (!found) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + } + _map_->alloc->free(entry); + _map_->count--; + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; + return 1; +} +size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values) +{ + if (hmm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + 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]); + if (*head == ((void *)0)) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + if (out_values) + { + size_t total = hmm_impl_key_count(_map_, key); + if (total == 0) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + *out_values = _map_->alloc->malloc(sizeof(size_t) * total); + if (!(*out_values)) + { + _map_->flag = CMC_FLAG_ALLOC; + return 0; + } + } + size_t index = 0; + struct hashmultimap_entry *entry = *head; + if (entry->next == ((void *)0)) + { + *head = ((void *)0); + *tail = ((void *)0); + if (out_values) + (*out_values)[index] = entry->value; + index++; + _map_->alloc->free(entry); + } + else + { + while (entry) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + { + if (*head == entry) + *head = entry->next; + if (*tail == entry) + *tail = entry->prev; + struct hashmultimap_entry *next = entry->next; + if (entry->prev) + entry->prev->next = entry->next; + if (entry->next) + 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 hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) +{ + if (hmm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + _Bool first = 1; + size_t max_key = (size_t){ 0 }; + size_t max_val = (size_t){ 0 }; + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) + { + if (first) + { + max_key = scan->key; + max_val = scan->value; + first = 0; + } + else if (_map_->f_key->cmp(scan->key, max_key) > 0) + { + max_key = scan->key; + max_val = scan->value; + } + scan = scan->next; + } + } + 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 1; +} +_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) +{ + if (hmm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + _Bool first = 1; + size_t min_key = (size_t){ 0 }; + size_t min_val = (size_t){ 0 }; + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) + { + if (first) + { + min_key = scan->key; + min_val = scan->value; + first = 0; + } + else if (_map_->f_key->cmp(scan->key, min_key) < 0) + { + min_key = scan->key; + min_val = scan->value; + } + scan = scan->next; + } + } + 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 1; +} +size_t hmm_get(struct hashmultimap *_map_, size_t key) +{ + if (hmm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); + if (!entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return (size_t){ 0 }; + } + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return entry->value; +} +size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) +{ + if (hmm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return ((void *)0); + } + struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); + if (!entry) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return ((void *)0); + } + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return &(entry->value); +} +_Bool hmm_contains(struct hashmultimap *_map_, size_t key) +{ + _map_->flag = CMC_FLAG_OK; + _Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return result; +} +_Bool hmm_empty(struct hashmultimap *_map_) +{ + return _map_->count == 0; +} +_Bool hmm_full(struct hashmultimap *_map_) +{ + return (double)_map_->capacity * _map_->load <= (double)_map_->count; +} +size_t hmm_count(struct hashmultimap *_map_) +{ + return _map_->count; +} +size_t hmm_key_count(struct hashmultimap *_map_, size_t key) +{ + return hmm_impl_key_count(_map_, key); +} +size_t hmm_capacity(struct hashmultimap *_map_) +{ + return _map_->capacity; +} +double hmm_load(struct hashmultimap *_map_) +{ + return _map_->load; +} +int hmm_flag(struct hashmultimap *_map_) +{ + return _map_->flag; +} +_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) +{ + _map_->flag = CMC_FLAG_OK; + if (_map_->capacity == capacity) + goto success; + if (_map_->capacity > capacity / _map_->load) + goto success; + if (capacity >= 0xffffffffffffffffULL * _map_->load) + { + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + size_t theoretical_size = hmm_impl_calculate_size(capacity); + if (theoretical_size < _map_->count / _map_->load) + { + _map_->flag = CMC_FLAG_INVALID; + return 0; + } + struct hashmultimap *_new_map_ = + hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); + if (!_new_map_) + { + _map_->flag = CMC_FLAG_ALLOC; + return 0; + } + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) + { + hmm_insert(_new_map_, scan->key, scan->value); + scan = scan->next; + } + } + if (_map_->count != _new_map_->count) + { + hmm_free(_new_map_); + _map_->flag = CMC_FLAG_ERROR; + return 0; + } + struct hashmultimap_entry *(*tmp_b)[2] = _map_->buffer; + _map_->buffer = _new_map_->buffer; + _new_map_->buffer = tmp_b; + size_t tmp_c = _map_->capacity; + _map_->capacity = _new_map_->capacity; + _new_map_->capacity = tmp_c; + _new_map_->f_key = &(struct hashmultimap_fkey){ ((void *)0) }; + _new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) }; + hmm_free(_new_map_); +success: + if ((_map_)->callbacks && (_map_)->callbacks->resize) + (_map_)->callbacks->resize(); + ; + return 1; +} +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)); + if (!result) + { + _map_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan) + { + size_t key; + size_t value; + if (_map_->f_key->cpy) + key = _map_->f_key->cpy(scan->key); + else + key = scan->key; + if (_map_->f_val->cpy) + value = _map_->f_val->cpy(scan->value); + else + value = scan->value; + hmm_insert(result, key, value); + scan = scan->next; + } + } + (result)->callbacks = _map_->callbacks; + _map_->flag = CMC_FLAG_OK; + return result; +} +_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_) +{ + _map1_->flag = CMC_FLAG_OK; + _map2_->flag = CMC_FLAG_OK; + if (_map1_->count != _map2_->count) + return 0; + struct hashmultimap *_map_a_; + struct hashmultimap *_map_b_; + _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; + _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; + for (size_t i = 0; i < _map_a_->capacity; i++) + { + struct hashmultimap_entry *scan = _map_a_->buffer[i][0]; + while (scan) + { + if (hmm_impl_key_count(_map_a_, scan->key) != hmm_impl_key_count(_map_b_, scan->key)) + return 0; + scan = scan->next; + } + } + return 1; +} +struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value) +{ + struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); + if (!entry) + return ((void *)0); + entry->key = key; + entry->value = value; + entry->next = ((void *)0); + entry->prev = ((void *)0); + return entry; +} +struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; + while (entry) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + return entry; + entry = entry->next; + } + return ((void *)0); +} +size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) +{ + size_t hash = _map_->f_key->hash(key); + struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; + size_t total_count = 0; + if (!entry) + return total_count; + while (entry) + { + if (_map_->f_key->cmp(entry->key, key) == 0) + total_count++; + entry = entry->next; + } + return total_count; +} +size_t hmm_impl_calculate_size(size_t required) +{ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; +} +struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) +{ + struct hashmultimap_iter iter; + iter.target = target; + iter.curr_entry = ((void *)0); + iter.cursor = 0; + iter.index = 0; + iter.first = 0; + iter.last = 0; + iter.start = 1; + iter.end = hmm_empty(target); + if (!hmm_empty(target)) + { + for (size_t i = 0; i < target->capacity; i++) + { + struct hashmultimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) + { + 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 hashmultimap_entry *entry = target->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) + { + iter.last = i - 1; + break; + } + } + } + return iter; +} +struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target) +{ + struct hashmultimap_iter iter; + iter.target = target; + iter.curr_entry = ((void *)0); + iter.cursor = 0; + iter.index = 0; + iter.first = 0; + iter.last = 0; + iter.start = hmm_empty(target); + iter.end = 1; + if (!hmm_empty(target)) + { + for (size_t i = 0; i < target->capacity; i++) + { + struct hashmultimap_entry *entry = target->buffer[i][0]; + if (entry && entry != ((void *)1)) + { + iter.first = i; + break; + } + } + for (size_t i = target->capacity; i > 0; i--) + { + struct hashmultimap_entry *entry = target->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) + { + iter.curr_entry = target->buffer[i - 1][1]; + iter.last = i - 1; + break; + } + } + iter.cursor = iter.last; + iter.index = target->count - 1; + } + return iter; +} +_Bool hmm_iter_at_start(struct hashmultimap_iter *iter) +{ + return hmm_empty(iter->target) || iter->start; +} +_Bool hmm_iter_at_end(struct hashmultimap_iter *iter) +{ + return hmm_empty(iter->target) || iter->end; +} +_Bool hmm_iter_to_start(struct hashmultimap_iter *iter) +{ + if (!hmm_empty(iter->target)) + { + iter->cursor = iter->first; + iter->index = 0; + iter->start = 1; + iter->end = hmm_empty(iter->target); + iter->curr_entry = iter->target->buffer[iter->first][0]; + return 1; + } + return 0; +} +_Bool hmm_iter_to_end(struct hashmultimap_iter *iter) +{ + if (!hmm_empty(iter->target)) + { + iter->cursor = iter->last; + iter->index = iter->target->count - 1; + iter->start = hmm_empty(iter->target); + iter->end = 1; + iter->curr_entry = iter->target->buffer[iter->last][1]; + return 1; + } + return 0; +} +_Bool hmm_iter_next(struct hashmultimap_iter *iter) +{ + if (iter->end) + return 0; + if (iter->curr_entry->next != ((void *)0)) + { + iter->curr_entry = iter->curr_entry->next; + iter->index++; + } + else + { + if (iter->cursor == iter->last) + { + iter->end = 1; + return 0; + } + iter->cursor++; + while (iter->target->buffer[iter->cursor][0] == ((void *)0)) + iter->cursor++; + iter->curr_entry = iter->target->buffer[iter->cursor][0]; + iter->index++; + } + iter->start = hmm_empty(iter->target); + return 1; +} +_Bool hmm_iter_prev(struct hashmultimap_iter *iter) +{ + if (iter->start) + return 0; + if (iter->curr_entry->prev != ((void *)0)) + { + iter->curr_entry = iter->curr_entry->prev; + iter->index--; + } + else + { + if (iter->cursor == iter->first) + { + iter->start = 1; + return 0; + } + iter->cursor--; + while (iter->target->buffer[iter->cursor][1] == ((void *)0)) + iter->cursor--; + iter->curr_entry = iter->target->buffer[iter->cursor][1]; + iter->index--; + } + iter->end = hmm_empty(iter->target); + return 1; +} +_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + for (size_t i = 0; i < steps; i++) + hmm_iter_next(iter); + return 1; +} +_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + for (size_t i = 0; i < steps; i++) + hmm_iter_prev(iter); + return 1; +} +_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return hmm_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return hmm_iter_advance(iter, index - iter->index); + return 1; +} +size_t hmm_iter_key(struct hashmultimap_iter *iter) +{ + if (hmm_empty(iter->target)) + return (size_t){ 0 }; + return iter->curr_entry->key; +} +size_t hmm_iter_value(struct hashmultimap_iter *iter) +{ + if (hmm_empty(iter->target)) + return (size_t){ 0 }; + return iter->curr_entry->value; +} +size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter) +{ + if (hmm_empty(iter->target)) + return ((void *)0); + return &(iter->curr_entry->value); +} +size_t hmm_iter_index(struct hashmultimap_iter *iter) +{ + return iter->index; +} +_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr) +{ + struct hashmultimap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_key:%p, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, + m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); +} +_Bool hmm_print(struct hashmultimap *_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 hashmultimap_entry *entry = _map_->buffer[i - 1][1]; + if (entry && entry != ((void *)1)) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _map_->capacity; i++) + { + struct hashmultimap_entry *scan = _map_->buffer[i][0]; + while (scan != ((void *)0)) + { + if (!_map_->f_key->str(fptr, scan->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, scan->value)) + return 0; + scan = scan->next; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_hashmultiset.c b/tests/src/tst_cmc_hashmultiset.c index 0a9f492..d10d4b8 100644 --- a/tests/src/tst_cmc_hashmultiset.c +++ b/tests/src/tst_cmc_hashmultiset.c @@ -1,7 +1,972 @@ - #include "tst_cmc_hashmultiset.h" +#include "tst_cmc_hashmultiset.h" - - 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) { return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); } struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_val) return ((void *)0); size_t real_capacity = hms_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); if (!_set_) return ((void *)0); _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); if (!_set_->buffer) { alloc->free(_set_); return ((void *)0); } _set_->count = 0; _set_->cardinality = 0; _set_->capacity = real_capacity; _set_->load = load; _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; (_set_)->callbacks = callbacks; return _set_; } void hms_clear(struct hashmultiset * _set_) { if (_set_->f_val->free) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashmultiset_entry *entry = &(_set_->buffer[i]); if (entry->state == CMC_ES_FILLED) { _set_->f_val->free(entry->value); } } } memset(_set_->buffer, 0, sizeof(struct hashmultiset_entry) * _set_->capacity); _set_->count = 0; _set_->flag = CMC_FLAG_OK; } void hms_free(struct hashmultiset * _set_) { if (_set_->f_val->free) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashmultiset_entry *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 hms_customize(struct hashmultiset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _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); if (!entry) { _set_->flag = CMC_FLAG_ERROR; return 0; } if (!new_node) entry->multiplicity++; _set_->cardinality++; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->create) (_set_)->callbacks->create();; return 1; } _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); if (!entry) { _set_->flag = CMC_FLAG_ERROR; return 0; } 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 1; } _Bool hms_update(struct hashmultiset * _set_, size_t value, size_t multiplicity) { if (multiplicity == 0) { struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); if (!result) goto success; _set_->count--; _set_->cardinality -= result->multiplicity; result->value = (size_t){ 0 }; result->multiplicity = 0; result->dist = 0; result->state = CMC_ES_DELETED; goto success; } _Bool 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; entry->multiplicity = multiplicity; success: _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->update) (_set_)->callbacks->update();; return 1; } _Bool hms_remove(struct hashmultiset * _set_, size_t value) { if (hms_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); if (!result) { _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (result->multiplicity > 1) result->multiplicity--; else { result->value = (size_t){ 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 1; } size_t hms_remove_all(struct hashmultiset * _set_, size_t value) { if (hms_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); if (!result) { _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } size_t removed = result->multiplicity; result->value = (size_t){ 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 hms_max(struct hashmultiset * _set_, size_t * value) { if (hms_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { if (first) { max_val = _set_->buffer[i].value; first = 0; } else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) { max_val = _set_->buffer[i].value; } } } if (value) *value = max_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool hms_min(struct hashmultiset * _set_, size_t * value) { if (hms_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t min_val = (size_t){ 0 }; for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { if (first) { min_val = _set_->buffer[i].value; first = 0; } else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) { min_val = _set_->buffer[i].value; } } } if (value) *value = min_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } size_t hms_multiplicity_of(struct hashmultiset * _set_, size_t value) { struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; if (!entry) return 0; return entry->multiplicity; } _Bool hms_contains(struct hashmultiset * _set_, size_t value) { _set_->flag = CMC_FLAG_OK; _Bool result = hms_impl_get_entry(_set_, value) != ((void *)0); if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return result; } _Bool hms_empty(struct hashmultiset * _set_) { return _set_->count == 0; } _Bool hms_full(struct hashmultiset * _set_) { return (double)_set_->capacity * _set_->load <= (double)_set_->count; } size_t hms_count(struct hashmultiset * _set_) { return _set_->count; } size_t hms_cardinality(struct hashmultiset * _set_) { return _set_->cardinality; } size_t hms_capacity(struct hashmultiset * _set_) { return _set_->capacity; } double hms_load(struct hashmultiset * _set_) { return _set_->load; } int hms_flag(struct hashmultiset * _set_) { return _set_->flag; } _Bool hms_resize(struct hashmultiset * _set_, size_t capacity) { _set_->flag = CMC_FLAG_OK; if (_set_->capacity == capacity) goto success; if (_set_->capacity > capacity / _set_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _set_->load) { _set_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hms_impl_calculate_size(capacity); if (theoretical_size < _set_->count / _set_->load) { _set_->flag = CMC_FLAG_INVALID; return 0; } struct hashmultiset *_new_set_ = hms_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!_new_set_) { _set_->flag = CMC_FLAG_ERROR; return 0; } for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { size_t value = _set_->buffer[i].value; size_t multiplicity = _set_->buffer[i].multiplicity; struct hashmultiset_entry *entry = hms_impl_insert_and_return(_new_set_, value, ((void *)0)); entry->multiplicity = multiplicity; } } if (_set_->count != _new_set_->count) { hms_free(_new_set_); _set_->flag = CMC_FLAG_ERROR; return 0; } struct hashmultiset_entry *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; _new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) }; hms_free(_new_set_); success: if ((_set_)->callbacks && (_set_)->callbacks->resize) (_set_)->callbacks->resize();; return 1; } struct hashmultiset *hms_copy_of(struct hashmultiset * _set_) { struct hashmultiset *result = hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _set_->callbacks; if (_set_->f_val->cpy) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashmultiset_entry *scan = &(_set_->buffer[i]); if (scan->state != CMC_ES_EMPTY) { struct hashmultiset_entry *target = &(result->buffer[i]); if (scan->state == CMC_ES_DELETED) target->state = CMC_ES_DELETED; else { target->state = scan->state; target->dist = scan->dist; target->multiplicity = scan->multiplicity; target->value = _set_->f_val->cpy(scan->value); } } } } else memcpy(result->buffer, _set_->buffer, sizeof(struct hashmultiset_entry) * _set_->capacity); result->count = _set_->count; result->cardinality = _set_->cardinality; _set_->flag = CMC_FLAG_OK; return result; } _Bool hms_equals(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; if (_set1_->cardinality != _set2_->cardinality) return 0; if (_set1_->count == 0) return 1; struct hashmultiset *_set_a_; struct hashmultiset *_set_b_; _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; for (size_t i = 0; i < _set_a_->capacity; i++) { if (_set_a_->buffer[i].state == CMC_ES_FILLED) { struct hashmultiset_entry *entry_a = &(_set_a_->buffer[i]); struct hashmultiset_entry *entry_b = hms_impl_get_entry(_set_b_, entry_a->value); if (!entry_b) return 0; if (entry_a->multiplicity != entry_b->multiplicity) return 0; } } return 1; } static size_t hms_impl_multiplicity_of(struct hashmultiset * _set_, size_t value) { struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); if (!entry) return 0; return entry->multiplicity; } static struct hashmultiset_entry * hms_impl_insert_and_return(struct hashmultiset * _set_, size_t value, _Bool *new_node) { if (new_node) *new_node = 0; struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); if (entry != ((void *)0)) return entry; if (new_node) *new_node = 1; if (hms_full(_set_)) { if (!hms_resize(_set_, _set_->capacity + 1)) return ((void *)0); } size_t hash = _set_->f_val->hash(value); size_t original_pos = hash % _set_->capacity; size_t pos = original_pos; size_t curr_mul = 1; struct hashmultiset_entry *target = &(_set_->buffer[pos]); struct hashmultiset_entry *to_return = ((void *)0); if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->value = value; target->multiplicity = curr_mul; target->dist = pos - original_pos; target->state = CMC_ES_FILLED; to_return = target; } else { while (1) { pos++; target = &(_set_->buffer[pos % _set_->capacity]); if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) { target->value = value; target->multiplicity = curr_mul; target->dist = pos - original_pos; target->state = CMC_ES_FILLED; if (!to_return) to_return = target; break; } else if (target->dist < pos - original_pos) { size_t tmp = target->value; size_t tmp_dist = target->dist; size_t tmp_mul = target->multiplicity; target->value = value; target->dist = pos - original_pos; target->multiplicity = curr_mul; value = tmp; original_pos = pos - tmp_dist; curr_mul = tmp_mul; if (!to_return) to_return = target; } } } _set_->count++; return to_return; } static struct hashmultiset_entry * hms_impl_get_entry(struct hashmultiset * _set_, size_t value) { size_t hash = _set_->f_val->hash(value); size_t pos = hash % _set_->capacity; struct hashmultiset_entry *target = &(_set_->buffer[pos]); while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) { if (_set_->f_val->cmp(target->value, value) == 0) return target; pos++; target = &(_set_->buffer[pos % _set_->capacity]); } return ((void *)0); } static size_t hms_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; while (cmc_hashtable_primes[i] < required) i++; return cmc_hashtable_primes[i]; } struct hashmultiset_iter hms_iter_start(struct hashmultiset * target) { struct hashmultiset_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = 1; iter.end = hms_empty(target); if (!hms_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 hashmultiset_iter hms_iter_end(struct hashmultiset * target) { struct hashmultiset_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = hms_empty(target); iter.end = 1; if (!hms_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 hms_iter_at_start(struct hashmultiset_iter * iter) { return hms_empty(iter->target) || iter->start; } _Bool hms_iter_at_end(struct hashmultiset_iter * iter) { return hms_empty(iter->target) || iter->end; } _Bool hms_iter_to_start(struct hashmultiset_iter * iter) { if (!hms_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = hms_empty(iter->target); return 1; } return 0; } _Bool hms_iter_to_end(struct hashmultiset_iter * iter) { if (!hms_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = hms_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool hms_iter_next(struct hashmultiset_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = hms_empty(iter->target); struct hashmultiset_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index++; while (1) { iter->cursor++; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hms_iter_prev(struct hashmultiset_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = hms_empty(iter->target); struct hashmultiset_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index--; while (1) { iter->cursor--; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hms_iter_advance(struct hashmultiset_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hms_iter_next(iter); return 1; } _Bool hms_iter_rewind(struct hashmultiset_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hms_iter_prev(iter); return 1; } _Bool hms_iter_go_to(struct hashmultiset_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hms_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hms_iter_advance(iter, index - iter->index); return 1; } size_t hms_iter_value(struct hashmultiset_iter * iter) { if (hms_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor].value; } size_t hms_iter_multiplicity(struct hashmultiset_iter * iter) { if (hms_empty(iter->target)) return 0; return iter->target->buffer[iter->cursor].multiplicity; } size_t hms_iter_index(struct hashmultiset_iter * iter) { return iter->index; } 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)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); struct hashmultiset_iter iter2 = hms_iter_start(_set2_); for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { size_t value = hms_iter_value(&iter1); size_t m1 = hms_iter_multiplicity(&iter1); size_t m2 = hms_impl_multiplicity_of(_set2_, value); size_t max_ = m1 > m2 ? m1 : m2; hms_update(_set_r_, value, max_); } for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { size_t value = hms_iter_value(&iter2); size_t m1 = hms_impl_multiplicity_of(_set1_, value); size_t m2 = hms_iter_multiplicity(&iter2); size_t max_ = m1 > m2 ? m1 : m2; hms_update(_set_r_, value, max_); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashmultiset *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)); if (!_set_r_) return ((void *)0); struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; struct hashmultiset_iter iter = hms_iter_start(_set_A_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); size_t m1 = hms_iter_multiplicity(&iter); size_t m2 = hms_impl_multiplicity_of(_set_B_, value); size_t max_ = m1 < m2 ? m1 : m2; hms_update(_set_r_, value, max_); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashmultiset *hms_difference(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { struct hashmultiset *_set_r_ = hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); size_t m1 = hms_iter_multiplicity(&iter); size_t m2 = hms_impl_multiplicity_of(_set2_, value); if (m1 > m2) hms_update(_set_r_, value, m1 - m2); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashmultiset *hms_summation(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { struct hashmultiset *_set_r_ = hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); struct hashmultiset_iter iter2 = hms_iter_start(_set2_); for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { hms_insert_many (_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); } for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { hms_insert_many (_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashmultiset *hms_symmetric_difference(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { struct hashmultiset *_set_r_ = hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct hashmultiset_iter iter1 = hms_iter_start(_set1_); struct hashmultiset_iter iter2 = hms_iter_start(_set2_); for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) { size_t value = hms_iter_value(&iter1); size_t m1 = hms_iter_multiplicity(&iter1); size_t m2 = hms_impl_multiplicity_of(_set2_, value); if (m1 != m2) { if (m1 > m2) hms_update(_set_r_, value, m1 - m2); else hms_update(_set_r_, value, m2 - m1); } } for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) { size_t value = hms_iter_value(&iter2); size_t m1 = hms_impl_multiplicity_of(_set1_, value); size_t m2 = hms_iter_multiplicity(&iter2); if (m1 != m2) { if (m1 > m2) hms_update(_set_r_, value, m1 - m2); else hms_update(_set_r_, value, m2 - m1); } } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } _Bool hms_is_subset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { if (_set1_->count > _set2_->count) return 0; if (hms_empty(_set1_)) return 1; struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); size_t m1 = hms_iter_multiplicity(&iter); size_t m2 = hms_impl_multiplicity_of(_set2_, value); if (m1 > m2) return 0; } return 1; } _Bool hms_is_superset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { return hms_is_subset(_set2_, _set1_); } _Bool hms_is_proper_subset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { if (_set1_->count >= _set2_->count) return 0; if (hms_empty(_set1_)) { if (!hms_empty(_set2_)) return 1; else return 0; } struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); size_t m1 = hms_iter_multiplicity(&iter); size_t m2 = hms_impl_multiplicity_of(_set2_, value); if (m1 >= m2) return 0; } return 1; } _Bool hms_is_proper_superset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { return hms_is_proper_subset(_set2_, _set1_); } _Bool hms_is_disjointset(struct hashmultiset * _set1_, struct hashmultiset * _set2_) { if (hms_empty(_set1_)) return 1; struct hashmultiset_iter iter = hms_iter_start(_set1_); for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) { size_t value = hms_iter_value(&iter); if (hms_impl_get_entry(_set2_, value) != ((void *)0)) return 0; } return 1; } _Bool hms_to_string(struct hashmultiset * _set_, FILE * fptr) { struct hashmultiset *s_ = _set_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "cardinality:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); } _Bool hms_print(struct hashmultiset * _set_, FILE * fptr, const char *start, const char *separator, const char *end, const char *val_mul_sep) { fprintf(fptr, "%s", start); size_t last = 0; for (size_t i = _set_->capacity; i > 0; i--) { if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) { last = i - 1; break; } } for (size_t i = 0; i < _set_->capacity; i++) { struct hashmultiset_entry *entry = &(_set_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (!_set_->f_val->str(fptr, entry->value)) return 0; fprintf(fptr, "%s", val_mul_sep); if (fprintf(fptr, "%" "I64u" "", entry->multiplicity) < 0) return 0; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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) +{ + return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); +} +struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (capacity == 0 || load <= 0 || load >= 1) + return ((void *)0); + if (capacity >= 0xffffffffffffffffULL * load) + return ((void *)0); + if (!f_val) + return ((void *)0); + size_t real_capacity = hms_impl_calculate_size(capacity / load); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); + if (!_set_) + return ((void *)0); + _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); + if (!_set_->buffer) + { + alloc->free(_set_); + return ((void *)0); + } + _set_->count = 0; + _set_->cardinality = 0; + _set_->capacity = real_capacity; + _set_->load = load; + _set_->flag = CMC_FLAG_OK; + _set_->f_val = f_val; + _set_->alloc = alloc; + (_set_)->callbacks = callbacks; + return _set_; +} +void hms_clear(struct hashmultiset *_set_) +{ + if (_set_->f_val->free) + { + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashmultiset_entry *entry = &(_set_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + _set_->f_val->free(entry->value); + } + } + } + memset(_set_->buffer, 0, sizeof(struct hashmultiset_entry) * _set_->capacity); + _set_->count = 0; + _set_->flag = CMC_FLAG_OK; +} +void hms_free(struct hashmultiset *_set_) +{ + if (_set_->f_val->free) + { + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashmultiset_entry *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 hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _set_->alloc = &cmc_alloc_node_default; + else + _set_->alloc = alloc; + (_set_)->callbacks = callbacks; + _set_->flag = CMC_FLAG_OK; +} +_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); + if (!entry) + { + _set_->flag = CMC_FLAG_ERROR; + return 0; + } + if (!new_node) + entry->multiplicity++; + _set_->cardinality++; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; + return 1; +} +_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); + if (!entry) + { + _set_->flag = CMC_FLAG_ERROR; + return 0; + } + 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 1; +} +_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) +{ + if (multiplicity == 0) + { + struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); + if (!result) + goto success; + _set_->count--; + _set_->cardinality -= result->multiplicity; + result->value = (size_t){ 0 }; + result->multiplicity = 0; + result->dist = 0; + result->state = CMC_ES_DELETED; + goto success; + } + _Bool 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; + entry->multiplicity = multiplicity; +success: + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->update) + (_set_)->callbacks->update(); + ; + return 1; +} +_Bool hms_remove(struct hashmultiset *_set_, size_t value) +{ + if (hms_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); + if (!result) + { + _set_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + if (result->multiplicity > 1) + result->multiplicity--; + else + { + result->value = (size_t){ 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 1; +} +size_t hms_remove_all(struct hashmultiset *_set_, size_t value) +{ + if (hms_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); + if (!result) + { + _set_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + size_t removed = result->multiplicity; + result->value = (size_t){ 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 hms_max(struct hashmultiset *_set_, size_t *value) +{ + if (hms_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + _Bool first = 1; + size_t max_val = (size_t){ 0 }; + for (size_t i = 0; i < _set_->capacity; i++) + { + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + max_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) + { + max_val = _set_->buffer[i].value; + } + } + } + if (value) + *value = max_val; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return 1; +} +_Bool hms_min(struct hashmultiset *_set_, size_t *value) +{ + if (hms_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + _Bool first = 1; + size_t min_val = (size_t){ 0 }; + for (size_t i = 0; i < _set_->capacity; i++) + { + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + min_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) + { + min_val = _set_->buffer[i].value; + } + } + } + if (value) + *value = min_val; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return 1; +} +size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value) +{ + struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + if (!entry) + return 0; + return entry->multiplicity; +} +_Bool hms_contains(struct hashmultiset *_set_, size_t value) +{ + _set_->flag = CMC_FLAG_OK; + _Bool result = hms_impl_get_entry(_set_, value) != ((void *)0); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return result; +} +_Bool hms_empty(struct hashmultiset *_set_) +{ + return _set_->count == 0; +} +_Bool hms_full(struct hashmultiset *_set_) +{ + return (double)_set_->capacity * _set_->load <= (double)_set_->count; +} +size_t hms_count(struct hashmultiset *_set_) +{ + return _set_->count; +} +size_t hms_cardinality(struct hashmultiset *_set_) +{ + return _set_->cardinality; +} +size_t hms_capacity(struct hashmultiset *_set_) +{ + return _set_->capacity; +} +double hms_load(struct hashmultiset *_set_) +{ + return _set_->load; +} +int hms_flag(struct hashmultiset *_set_) +{ + return _set_->flag; +} +_Bool hms_resize(struct hashmultiset *_set_, size_t capacity) +{ + _set_->flag = CMC_FLAG_OK; + if (_set_->capacity == capacity) + goto success; + if (_set_->capacity > capacity / _set_->load) + goto success; + if (capacity >= 0xffffffffffffffffULL * _set_->load) + { + _set_->flag = CMC_FLAG_ERROR; + return 0; + } + size_t theoretical_size = hms_impl_calculate_size(capacity); + if (theoretical_size < _set_->count / _set_->load) + { + _set_->flag = CMC_FLAG_INVALID; + return 0; + } + struct hashmultiset *_new_set_ = hms_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); + if (!_new_set_) + { + _set_->flag = CMC_FLAG_ERROR; + return 0; + } + for (size_t i = 0; i < _set_->capacity; i++) + { + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + size_t value = _set_->buffer[i].value; + size_t multiplicity = _set_->buffer[i].multiplicity; + struct hashmultiset_entry *entry = hms_impl_insert_and_return(_new_set_, value, ((void *)0)); + entry->multiplicity = multiplicity; + } + } + if (_set_->count != _new_set_->count) + { + hms_free(_new_set_); + _set_->flag = CMC_FLAG_ERROR; + return 0; + } + struct hashmultiset_entry *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; + _new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) }; + hms_free(_new_set_); +success: + if ((_set_)->callbacks && (_set_)->callbacks->resize) + (_set_)->callbacks->resize(); + ; + return 1; +} +struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) +{ + struct hashmultiset *result = + hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); + if (!result) + { + _set_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _set_->callbacks; + if (_set_->f_val->cpy) + { + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashmultiset_entry *scan = &(_set_->buffer[i]); + if (scan->state != CMC_ES_EMPTY) + { + struct hashmultiset_entry *target = &(result->buffer[i]); + if (scan->state == CMC_ES_DELETED) + target->state = CMC_ES_DELETED; + else + { + target->state = scan->state; + target->dist = scan->dist; + target->multiplicity = scan->multiplicity; + target->value = _set_->f_val->cpy(scan->value); + } + } + } + } + else + memcpy(result->buffer, _set_->buffer, sizeof(struct hashmultiset_entry) * _set_->capacity); + result->count = _set_->count; + result->cardinality = _set_->cardinality; + _set_->flag = CMC_FLAG_OK; + return result; +} +_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count != _set2_->count) + return 0; + if (_set1_->cardinality != _set2_->cardinality) + return 0; + if (_set1_->count == 0) + return 1; + struct hashmultiset *_set_a_; + struct hashmultiset *_set_b_; + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; + for (size_t i = 0; i < _set_a_->capacity; i++) + { + if (_set_a_->buffer[i].state == CMC_ES_FILLED) + { + struct hashmultiset_entry *entry_a = &(_set_a_->buffer[i]); + struct hashmultiset_entry *entry_b = hms_impl_get_entry(_set_b_, entry_a->value); + if (!entry_b) + return 0; + if (entry_a->multiplicity != entry_b->multiplicity) + return 0; + } + } + return 1; +} +static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) +{ + struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); + if (!entry) + return 0; + return entry->multiplicity; +} +static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) +{ + if (new_node) + *new_node = 0; + struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); + if (entry != ((void *)0)) + return entry; + if (new_node) + *new_node = 1; + if (hms_full(_set_)) + { + if (!hms_resize(_set_, _set_->capacity + 1)) + return ((void *)0); + } + size_t hash = _set_->f_val->hash(value); + size_t original_pos = hash % _set_->capacity; + size_t pos = original_pos; + size_t curr_mul = 1; + struct hashmultiset_entry *target = &(_set_->buffer[pos]); + struct hashmultiset_entry *to_return = ((void *)0); + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) + { + target->value = value; + target->multiplicity = curr_mul; + target->dist = pos - original_pos; + target->state = CMC_ES_FILLED; + to_return = target; + } + else + { + while (1) + { + pos++; + target = &(_set_->buffer[pos % _set_->capacity]); + if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) + { + target->value = value; + target->multiplicity = curr_mul; + target->dist = pos - original_pos; + target->state = CMC_ES_FILLED; + if (!to_return) + to_return = target; + break; + } + else if (target->dist < pos - original_pos) + { + size_t tmp = target->value; + size_t tmp_dist = target->dist; + size_t tmp_mul = target->multiplicity; + target->value = value; + target->dist = pos - original_pos; + target->multiplicity = curr_mul; + value = tmp; + original_pos = pos - tmp_dist; + curr_mul = tmp_mul; + if (!to_return) + to_return = target; + } + } + } + _set_->count++; + return to_return; +} +static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value) +{ + size_t hash = _set_->f_val->hash(value); + size_t pos = hash % _set_->capacity; + struct hashmultiset_entry *target = &(_set_->buffer[pos]); + while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) + { + if (_set_->f_val->cmp(target->value, value) == 0) + return target; + pos++; + target = &(_set_->buffer[pos % _set_->capacity]); + } + return ((void *)0); +} +static size_t hms_impl_calculate_size(size_t required) +{ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; +} +struct hashmultiset_iter hms_iter_start(struct hashmultiset *target) +{ + struct hashmultiset_iter iter; + iter.target = target; + iter.cursor = 0; + iter.index = 0; + iter.first = 0; + iter.last = 0; + iter.start = 1; + iter.end = hms_empty(target); + if (!hms_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 hashmultiset_iter hms_iter_end(struct hashmultiset *target) +{ + struct hashmultiset_iter iter; + iter.target = target; + iter.cursor = 0; + iter.index = 0; + iter.first = 0; + iter.last = 0; + iter.start = hms_empty(target); + iter.end = 1; + if (!hms_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 hms_iter_at_start(struct hashmultiset_iter *iter) +{ + return hms_empty(iter->target) || iter->start; +} +_Bool hms_iter_at_end(struct hashmultiset_iter *iter) +{ + return hms_empty(iter->target) || iter->end; +} +_Bool hms_iter_to_start(struct hashmultiset_iter *iter) +{ + if (!hms_empty(iter->target)) + { + iter->cursor = iter->first; + iter->index = 0; + iter->start = 1; + iter->end = hms_empty(iter->target); + return 1; + } + return 0; +} +_Bool hms_iter_to_end(struct hashmultiset_iter *iter) +{ + if (!hms_empty(iter->target)) + { + iter->cursor = iter->last; + iter->index = iter->target->count - 1; + iter->start = hms_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool hms_iter_next(struct hashmultiset_iter *iter) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = hms_empty(iter->target); + struct hashmultiset_entry *scan = &(iter->target->buffer[iter->cursor]); + iter->index++; + while (1) + { + iter->cursor++; + scan = &(iter->target->buffer[iter->cursor]); + if (scan->state == CMC_ES_FILLED) + break; + } + return 1; +} +_Bool hms_iter_prev(struct hashmultiset_iter *iter) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + iter->end = hms_empty(iter->target); + struct hashmultiset_entry *scan = &(iter->target->buffer[iter->cursor]); + iter->index--; + while (1) + { + iter->cursor--; + scan = &(iter->target->buffer[iter->cursor]); + if (scan->state == CMC_ES_FILLED) + break; + } + return 1; +} +_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + for (size_t i = 0; i < steps; i++) + hms_iter_next(iter); + return 1; +} +_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + for (size_t i = 0; i < steps; i++) + hms_iter_prev(iter); + return 1; +} +_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return hms_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return hms_iter_advance(iter, index - iter->index); + return 1; +} +size_t hms_iter_value(struct hashmultiset_iter *iter) +{ + if (hms_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor].value; +} +size_t hms_iter_multiplicity(struct hashmultiset_iter *iter) +{ + if (hms_empty(iter->target)) + return 0; + return iter->target->buffer[iter->cursor].multiplicity; +} +size_t hms_iter_index(struct hashmultiset_iter *iter) +{ + return iter->index; +} +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)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + { + size_t value = hms_iter_value(&iter1); + size_t m1 = hms_iter_multiplicity(&iter1); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + size_t max_ = m1 > m2 ? m1 : m2; + hms_update(_set_r_, value, max_); + } + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) + { + size_t value = hms_iter_value(&iter2); + size_t m1 = hms_impl_multiplicity_of(_set1_, value); + size_t m2 = hms_iter_multiplicity(&iter2); + size_t max_ = m1 > m2 ? m1 : m2; + hms_update(_set_r_, value, max_); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *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)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct hashmultiset_iter iter = hms_iter_start(_set_A_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set_B_, value); + size_t max_ = m1 < m2 ? m1 : m2; + hms_update(_set_r_, value, max_); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + { + hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); + } + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) + { + hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + struct hashmultiset *_set_r_ = + hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct hashmultiset_iter iter1 = hms_iter_start(_set1_); + struct hashmultiset_iter iter2 = hms_iter_start(_set2_); + for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) + { + size_t value = hms_iter_value(&iter1); + size_t m1 = hms_iter_multiplicity(&iter1); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 != m2) + { + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); + else + hms_update(_set_r_, value, m2 - m1); + } + } + for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) + { + size_t value = hms_iter_value(&iter2); + size_t m1 = hms_impl_multiplicity_of(_set1_, value); + size_t m2 = hms_iter_multiplicity(&iter2); + if (m1 != m2) + { + if (m1 > m2) + hms_update(_set_r_, value, m1 - m2); + else + hms_update(_set_r_, value, m2 - m1); + } + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + if (_set1_->count > _set2_->count) + return 0; + if (hms_empty(_set1_)) + return 1; + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 > m2) + return 0; + } + return 1; +} +_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + return hms_is_subset(_set2_, _set1_); +} +_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + if (_set1_->count >= _set2_->count) + return 0; + if (hms_empty(_set1_)) + { + if (!hms_empty(_set2_)) + return 1; + else + return 0; + } + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + size_t m1 = hms_iter_multiplicity(&iter); + size_t m2 = hms_impl_multiplicity_of(_set2_, value); + if (m1 >= m2) + return 0; + } + return 1; +} +_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + return hms_is_proper_subset(_set2_, _set1_); +} +_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) +{ + if (hms_empty(_set1_)) + return 1; + struct hashmultiset_iter iter = hms_iter_start(_set1_); + for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + { + size_t value = hms_iter_value(&iter); + if (hms_impl_get_entry(_set2_, value) != ((void *)0)) + return 0; + } + return 1; +} +_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr) +{ + struct hashmultiset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "cardinality:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load, + s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); +} +_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *val_mul_sep) +{ + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _set_->capacity; i > 0; i--) + { + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashmultiset_entry *entry = &(_set_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_set_->f_val->str(fptr, entry->value)) + return 0; + fprintf(fptr, "%s", val_mul_sep); + if (fprintf(fptr, + "%" + "I64u" + "", + entry->multiplicity) < 0) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_hashset.c b/tests/src/tst_cmc_hashset.c index f82410a..1e4764b 100644 --- a/tests/src/tst_cmc_hashset.c +++ b/tests/src/tst_cmc_hashset.c @@ -1,7 +1,773 @@ - #include "tst_cmc_hashset.h" +#include "tst_cmc_hashset.h" - - static struct hashset_entry * hs_impl_get_entry(struct hashset * _set_, size_t value); static size_t hs_impl_calculate_size(size_t required); struct hashset *hs_new(size_t capacity, double load, struct hashset_fval * f_val) { return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); } struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || load <= 0 || load >= 1) return ((void *)0); if (capacity >= 0xffffffffffffffffULL * load) return ((void *)0); if (!f_val) return ((void *)0); size_t real_capacity = hs_impl_calculate_size(capacity / load); if (!alloc) alloc = &cmc_alloc_node_default; struct hashset *_set_ = alloc->malloc(sizeof(struct hashset)); if (!_set_) return ((void *)0); _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry)); if (!_set_->buffer) { alloc->free(_set_); return ((void *)0); } _set_->count = 0; _set_->capacity = real_capacity; _set_->load = load; _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; (_set_)->callbacks = callbacks; return _set_; } void hs_clear(struct hashset * _set_) { if (_set_->f_val->free) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashset_entry *entry = &(_set_->buffer[i]); if (entry->state == CMC_ES_FILLED) { _set_->f_val->free(entry->value); } } } memset(_set_->buffer, 0, sizeof(struct hashset_entry) * _set_->capacity); _set_->count = 0; _set_->flag = CMC_FLAG_OK; } void hs_free(struct hashset * _set_) { if (_set_->f_val->free) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashset_entry *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 hs_customize(struct hashset * _set_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool hs_insert(struct hashset * _set_, size_t value) { if (hs_full(_set_)) { if (!hs_resize(_set_, _set_->capacity + 1)) return 0; } if (hs_impl_get_entry(_set_, value) != ((void *)0)) { _set_->flag = CMC_FLAG_DUPLICATE; return 0; } size_t hash = _set_->f_val->hash(value); size_t original_pos = hash % _set_->capacity; size_t pos = original_pos; struct hashset_entry *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 (1) { 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) { size_t 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 1; } _Bool hs_remove(struct hashset * _set_, size_t value) { if (hs_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct hashset_entry *result = hs_impl_get_entry(_set_, value); if (result == ((void *)0)) { _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } result->value = (size_t){ 0 }; result->dist = 0; result->state = CMC_ES_DELETED; _set_->count--; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->delete) (_set_)->callbacks->delete();; return 1; } _Bool hs_max(struct hashset * _set_, size_t * value) { if (hs_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { if (first) { max_val = _set_->buffer[i].value; first = 0; } else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) { max_val = _set_->buffer[i].value; } } } if (value) *value = max_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool hs_min(struct hashset * _set_, size_t * value) { if (hs_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } _Bool first = 1; size_t min_val = (size_t){ 0 }; for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { if (first) { min_val = _set_->buffer[i].value; first = 0; } else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) { min_val = _set_->buffer[i].value; } } } if (value) *value = min_val; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool hs_contains(struct hashset * _set_, size_t value) { _set_->flag = CMC_FLAG_OK; _Bool result = hs_impl_get_entry(_set_, value) != ((void *)0); if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return result; } _Bool hs_empty(struct hashset * _set_) { return _set_->count == 0; } _Bool hs_full(struct hashset * _set_) { return (double)_set_->capacity * _set_->load <= (double)_set_->count; } size_t hs_count(struct hashset * _set_) { return _set_->count; } size_t hs_capacity(struct hashset * _set_) { return _set_->capacity; } double hs_load(struct hashset * _set_) { return _set_->load; } int hs_flag(struct hashset * _set_) { return _set_->flag; } _Bool hs_resize(struct hashset * _set_, size_t capacity) { _set_->flag = CMC_FLAG_OK; if (_set_->capacity == capacity) goto success; if (_set_->capacity > capacity / _set_->load) goto success; if (capacity >= 0xffffffffffffffffULL * _set_->load) { _set_->flag = CMC_FLAG_ERROR; return 0; } size_t theoretical_size = hs_impl_calculate_size(capacity); if (theoretical_size < _set_->count / _set_->load) { _set_->flag = CMC_FLAG_INVALID; return 0; } struct hashset *_new_set_ = hs_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!_new_set_) { _set_->flag = CMC_FLAG_ALLOC; return 0; } for (size_t i = 0; i < _set_->capacity; i++) { if (_set_->buffer[i].state == CMC_ES_FILLED) { size_t value = _set_->buffer[i].value; hs_insert(_new_set_, value); } } if (_set_->count != _new_set_->count) { hs_free(_new_set_); _set_->flag = CMC_FLAG_ERROR; return 0; } struct hashset_entry *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; _new_set_->f_val = &(struct hashset_fval){ ((void *)0) }; hs_free(_new_set_); success: if ((_set_)->callbacks && (_set_)->callbacks->resize) (_set_)->callbacks->resize();; return 1; } struct hashset *hs_copy_of(struct hashset * _set_) { struct hashset *result = hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _set_->callbacks; if (_set_->f_val->cpy) { for (size_t i = 0; i < _set_->capacity; i++) { struct hashset_entry *scan = &(_set_->buffer[i]); if (scan->state != CMC_ES_EMPTY) { struct hashset_entry *target = &(result->buffer[i]); if (scan->state == CMC_ES_DELETED) target->state = CMC_ES_DELETED; else { target->state = scan->state; target->dist = scan->dist; target->value = _set_->f_val->cpy(scan->value); } } } } else memcpy(result->buffer, _set_->buffer, sizeof(struct hashset_entry) * _set_->capacity); result->count = _set_->count; _set_->flag = CMC_FLAG_OK; return result; } _Bool hs_equals(struct hashset * _set1_, struct hashset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; struct hashset *_set_a_; struct hashset *_set_b_; _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; for (size_t i = 0; i < _set_a_->capacity; i++) { if (_set_a_->buffer[i].state == CMC_ES_FILLED) { if (!hs_impl_get_entry(_set_b_, _set_a_->buffer[i].value)) return 0; } } return 1; } 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; struct hashset_entry *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 ((void *)0); } static size_t hs_impl_calculate_size(size_t required) { const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); if (cmc_hashtable_primes[count - 1] < required) return required; size_t i = 0; while (cmc_hashtable_primes[i] < required) i++; return cmc_hashtable_primes[i]; } struct hashset_iter hs_iter_start(struct hashset * target) { struct hashset_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = 1; iter.end = hs_empty(target); if (!hs_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 hashset_iter hs_iter_end(struct hashset * target) { struct hashset_iter iter; iter.target = target; iter.cursor = 0; iter.index = 0; iter.first = 0; iter.last = 0; iter.start = hs_empty(target); iter.end = 1; if (!hs_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 hs_iter_at_start(struct hashset_iter * iter) { return hs_empty(iter->target) || iter->start; } _Bool hs_iter_at_end(struct hashset_iter * iter) { return hs_empty(iter->target) || iter->end; } _Bool hs_iter_to_start(struct hashset_iter * iter) { if (!hs_empty(iter->target)) { iter->cursor = iter->first; iter->index = 0; iter->start = 1; iter->end = hs_empty(iter->target); return 1; } return 0; } _Bool hs_iter_to_end(struct hashset_iter * iter) { if (!hs_empty(iter->target)) { iter->cursor = iter->last; iter->index = iter->target->count - 1; iter->start = hs_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool hs_iter_next(struct hashset_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = hs_empty(iter->target); struct hashset_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index++; while (1) { iter->cursor++; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hs_iter_prev(struct hashset_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = hs_empty(iter->target); struct hashset_entry *scan = &(iter->target->buffer[iter->cursor]); iter->index--; while (1) { iter->cursor--; scan = &(iter->target->buffer[iter->cursor]); if (scan->state == CMC_ES_FILLED) break; } return 1; } _Bool hs_iter_advance(struct hashset_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) hs_iter_next(iter); return 1; } _Bool hs_iter_rewind(struct hashset_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) hs_iter_prev(iter); return 1; } _Bool hs_iter_go_to(struct hashset_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return hs_iter_rewind(iter, iter->index - index); else if (iter->index < index) return hs_iter_advance(iter, index - iter->index); return 1; } size_t hs_iter_value(struct hashset_iter * iter) { if (hs_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor].value; } size_t hs_iter_index(struct hashset_iter * iter) { return iter->index; } 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)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter1 = hs_iter_start(_set1_); struct hashset_iter iter2 = hs_iter_start(_set2_); for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) { hs_insert(_set_r_, hs_iter_value(&iter1)); } for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) { hs_insert(_set_r_, hs_iter_value(&iter2)); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } 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)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; struct hashset_iter iter = hs_iter_start(_set_A_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) hs_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashset *hs_difference(struct hashset * _set1_, struct hashset * _set2_) { struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter = hs_iter_start(_set1_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set2_, value) == ((void *)0)) hs_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct hashset *hs_symmetric_difference(struct hashset * _set1_, struct hashset * _set2_) { struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) { _set1_->flag = CMC_FLAG_ALLOC; _set2_->flag = CMC_FLAG_ALLOC; return ((void *)0); } struct hashset_iter iter1 = hs_iter_start(_set1_); struct hashset_iter iter2 = hs_iter_start(_set2_); for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) { size_t value = hs_iter_value(&iter1); if (hs_impl_get_entry(_set2_, value) == ((void *)0)) hs_insert(_set_r_, value); } for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) { size_t value = hs_iter_value(&iter2); if (hs_impl_get_entry(_set1_, value) == ((void *)0)) hs_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } _Bool hs_is_subset(struct hashset * _set1_, struct hashset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count > _set2_->count) return 0; if (hs_empty(_set1_)) return 1; struct hashset_iter iter = hs_iter_start(_set1_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set2_, value) == ((void *)0)) return 0; } return 1; } _Bool hs_is_superset(struct hashset * _set1_, struct hashset * _set2_) { return hs_is_subset(_set2_, _set1_); } _Bool hs_is_proper_subset(struct hashset * _set1_, struct hashset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count >= _set2_->count) return 0; if (hs_empty(_set1_)) { if (!hs_empty(_set2_)) return 1; else return 0; } struct hashset_iter iter = hs_iter_start(_set1_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set2_, value) == ((void *)0)) return 0; } return 1; } _Bool hs_is_proper_superset(struct hashset * _set1_, struct hashset * _set2_) { return hs_is_proper_subset(_set2_, _set1_); } _Bool hs_is_disjointset(struct hashset * _set1_, struct hashset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (hs_empty(_set1_)) return 1; struct hashset_iter iter = hs_iter_start(_set1_); for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) { size_t value = hs_iter_value(&iter); if (hs_impl_get_entry(_set2_, value) != ((void *)0)) return 0; } return 1; } _Bool hs_to_string(struct hashset * _set_, FILE * fptr) { struct hashset *s_ = _set_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "load:%lf, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks: %p }", "hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); } _Bool hs_print(struct hashset * _set_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); size_t last = 0; for (size_t i = _set_->capacity; i > 0; i--) { if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) { last = i - 1; break; } } for (size_t i = 0; i < _set_->capacity; i++) { struct hashset_entry *entry = &(_set_->buffer[i]); if (entry->state == CMC_ES_FILLED) { if (!_set_->f_val->str(fptr, entry->value)) return 0; if (i + 1 < last) fprintf(fptr, "%s", separator); } } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value); +static size_t hs_impl_calculate_size(size_t required); +struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val) +{ + return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); +} +struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (capacity == 0 || load <= 0 || load >= 1) + return ((void *)0); + if (capacity >= 0xffffffffffffffffULL * load) + return ((void *)0); + if (!f_val) + return ((void *)0); + size_t real_capacity = hs_impl_calculate_size(capacity / load); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct hashset *_set_ = alloc->malloc(sizeof(struct hashset)); + if (!_set_) + return ((void *)0); + _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry)); + if (!_set_->buffer) + { + alloc->free(_set_); + return ((void *)0); + } + _set_->count = 0; + _set_->capacity = real_capacity; + _set_->load = load; + _set_->flag = CMC_FLAG_OK; + _set_->f_val = f_val; + _set_->alloc = alloc; + (_set_)->callbacks = callbacks; + return _set_; +} +void hs_clear(struct hashset *_set_) +{ + if (_set_->f_val->free) + { + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashset_entry *entry = &(_set_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + _set_->f_val->free(entry->value); + } + } + } + memset(_set_->buffer, 0, sizeof(struct hashset_entry) * _set_->capacity); + _set_->count = 0; + _set_->flag = CMC_FLAG_OK; +} +void hs_free(struct hashset *_set_) +{ + if (_set_->f_val->free) + { + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashset_entry *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 hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _set_->alloc = &cmc_alloc_node_default; + else + _set_->alloc = alloc; + (_set_)->callbacks = callbacks; + _set_->flag = CMC_FLAG_OK; +} +_Bool hs_insert(struct hashset *_set_, size_t value) +{ + if (hs_full(_set_)) + { + if (!hs_resize(_set_, _set_->capacity + 1)) + return 0; + } + if (hs_impl_get_entry(_set_, value) != ((void *)0)) + { + _set_->flag = CMC_FLAG_DUPLICATE; + return 0; + } + size_t hash = _set_->f_val->hash(value); + size_t original_pos = hash % _set_->capacity; + size_t pos = original_pos; + struct hashset_entry *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 (1) + { + 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) + { + size_t 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 1; +} +_Bool hs_remove(struct hashset *_set_, size_t value) +{ + if (hs_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct hashset_entry *result = hs_impl_get_entry(_set_, value); + if (result == ((void *)0)) + { + _set_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + result->value = (size_t){ 0 }; + result->dist = 0; + result->state = CMC_ES_DELETED; + _set_->count--; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; + return 1; +} +_Bool hs_max(struct hashset *_set_, size_t *value) +{ + if (hs_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + _Bool first = 1; + size_t max_val = (size_t){ 0 }; + for (size_t i = 0; i < _set_->capacity; i++) + { + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + max_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) + { + max_val = _set_->buffer[i].value; + } + } + } + if (value) + *value = max_val; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return 1; +} +_Bool hs_min(struct hashset *_set_, size_t *value) +{ + if (hs_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + _Bool first = 1; + size_t min_val = (size_t){ 0 }; + for (size_t i = 0; i < _set_->capacity; i++) + { + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + min_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) + { + min_val = _set_->buffer[i].value; + } + } + } + if (value) + *value = min_val; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return 1; +} +_Bool hs_contains(struct hashset *_set_, size_t value) +{ + _set_->flag = CMC_FLAG_OK; + _Bool result = hs_impl_get_entry(_set_, value) != ((void *)0); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return result; +} +_Bool hs_empty(struct hashset *_set_) +{ + return _set_->count == 0; +} +_Bool hs_full(struct hashset *_set_) +{ + return (double)_set_->capacity * _set_->load <= (double)_set_->count; +} +size_t hs_count(struct hashset *_set_) +{ + return _set_->count; +} +size_t hs_capacity(struct hashset *_set_) +{ + return _set_->capacity; +} +double hs_load(struct hashset *_set_) +{ + return _set_->load; +} +int hs_flag(struct hashset *_set_) +{ + return _set_->flag; +} +_Bool hs_resize(struct hashset *_set_, size_t capacity) +{ + _set_->flag = CMC_FLAG_OK; + if (_set_->capacity == capacity) + goto success; + if (_set_->capacity > capacity / _set_->load) + goto success; + if (capacity >= 0xffffffffffffffffULL * _set_->load) + { + _set_->flag = CMC_FLAG_ERROR; + return 0; + } + size_t theoretical_size = hs_impl_calculate_size(capacity); + if (theoretical_size < _set_->count / _set_->load) + { + _set_->flag = CMC_FLAG_INVALID; + return 0; + } + struct hashset *_new_set_ = hs_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); + if (!_new_set_) + { + _set_->flag = CMC_FLAG_ALLOC; + return 0; + } + for (size_t i = 0; i < _set_->capacity; i++) + { + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + size_t value = _set_->buffer[i].value; + hs_insert(_new_set_, value); + } + } + if (_set_->count != _new_set_->count) + { + hs_free(_new_set_); + _set_->flag = CMC_FLAG_ERROR; + return 0; + } + struct hashset_entry *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; + _new_set_->f_val = &(struct hashset_fval){ ((void *)0) }; + hs_free(_new_set_); +success: + if ((_set_)->callbacks && (_set_)->callbacks->resize) + (_set_)->callbacks->resize(); + ; + return 1; +} +struct hashset *hs_copy_of(struct hashset *_set_) +{ + struct hashset *result = + hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); + if (!result) + { + _set_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _set_->callbacks; + if (_set_->f_val->cpy) + { + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashset_entry *scan = &(_set_->buffer[i]); + if (scan->state != CMC_ES_EMPTY) + { + struct hashset_entry *target = &(result->buffer[i]); + if (scan->state == CMC_ES_DELETED) + target->state = CMC_ES_DELETED; + else + { + target->state = scan->state; + target->dist = scan->dist; + target->value = _set_->f_val->cpy(scan->value); + } + } + } + } + else + memcpy(result->buffer, _set_->buffer, sizeof(struct hashset_entry) * _set_->capacity); + result->count = _set_->count; + _set_->flag = CMC_FLAG_OK; + return result; +} +_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count != _set2_->count) + return 0; + struct hashset *_set_a_; + struct hashset *_set_b_; + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; + for (size_t i = 0; i < _set_a_->capacity; i++) + { + if (_set_a_->buffer[i].state == CMC_ES_FILLED) + { + if (!hs_impl_get_entry(_set_b_, _set_a_->buffer[i].value)) + return 0; + } + } + return 1; +} +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; + struct hashset_entry *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 ((void *)0); +} +static size_t hs_impl_calculate_size(size_t required) +{ + const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); + if (cmc_hashtable_primes[count - 1] < required) + return required; + size_t i = 0; + while (cmc_hashtable_primes[i] < required) + i++; + return cmc_hashtable_primes[i]; +} +struct hashset_iter hs_iter_start(struct hashset *target) +{ + struct hashset_iter iter; + iter.target = target; + iter.cursor = 0; + iter.index = 0; + iter.first = 0; + iter.last = 0; + iter.start = 1; + iter.end = hs_empty(target); + if (!hs_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 hashset_iter hs_iter_end(struct hashset *target) +{ + struct hashset_iter iter; + iter.target = target; + iter.cursor = 0; + iter.index = 0; + iter.first = 0; + iter.last = 0; + iter.start = hs_empty(target); + iter.end = 1; + if (!hs_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 hs_iter_at_start(struct hashset_iter *iter) +{ + return hs_empty(iter->target) || iter->start; +} +_Bool hs_iter_at_end(struct hashset_iter *iter) +{ + return hs_empty(iter->target) || iter->end; +} +_Bool hs_iter_to_start(struct hashset_iter *iter) +{ + if (!hs_empty(iter->target)) + { + iter->cursor = iter->first; + iter->index = 0; + iter->start = 1; + iter->end = hs_empty(iter->target); + return 1; + } + return 0; +} +_Bool hs_iter_to_end(struct hashset_iter *iter) +{ + if (!hs_empty(iter->target)) + { + iter->cursor = iter->last; + iter->index = iter->target->count - 1; + iter->start = hs_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool hs_iter_next(struct hashset_iter *iter) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = hs_empty(iter->target); + struct hashset_entry *scan = &(iter->target->buffer[iter->cursor]); + iter->index++; + while (1) + { + iter->cursor++; + scan = &(iter->target->buffer[iter->cursor]); + if (scan->state == CMC_ES_FILLED) + break; + } + return 1; +} +_Bool hs_iter_prev(struct hashset_iter *iter) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + iter->end = hs_empty(iter->target); + struct hashset_entry *scan = &(iter->target->buffer[iter->cursor]); + iter->index--; + while (1) + { + iter->cursor--; + scan = &(iter->target->buffer[iter->cursor]); + if (scan->state == CMC_ES_FILLED) + break; + } + return 1; +} +_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + for (size_t i = 0; i < steps; i++) + hs_iter_next(iter); + return 1; +} +_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + for (size_t i = 0; i < steps; i++) + hs_iter_prev(iter); + return 1; +} +_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return hs_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return hs_iter_advance(iter, index - iter->index); + return 1; +} +size_t hs_iter_value(struct hashset_iter *iter) +{ + if (hs_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor].value; +} +size_t hs_iter_index(struct hashset_iter *iter) +{ + return iter->index; +} +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)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset_iter iter1 = hs_iter_start(_set1_); + struct hashset_iter iter2 = hs_iter_start(_set2_); + for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) + { + hs_insert(_set_r_, hs_iter_value(&iter1)); + } + for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) + { + hs_insert(_set_r_, hs_iter_value(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +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)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct hashset_iter iter = hs_iter_start(_set_A_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) +{ + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_) +{ + struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + { + _set1_->flag = CMC_FLAG_ALLOC; + _set2_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + struct hashset_iter iter1 = hs_iter_start(_set1_); + struct hashset_iter iter2 = hs_iter_start(_set2_); + for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) + { + size_t value = hs_iter_value(&iter1); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) + { + size_t value = hs_iter_value(&iter2); + if (hs_impl_get_entry(_set1_, value) == ((void *)0)) + hs_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count > _set2_->count) + return 0; + if (hs_empty(_set1_)) + return 1; + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_) +{ + return hs_is_subset(_set2_, _set1_); +} +_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count >= _set2_->count) + return 0; + if (hs_empty(_set1_)) + { + if (!hs_empty(_set2_)) + return 1; + else + return 0; + } + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) == ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_) +{ + return hs_is_proper_subset(_set2_, _set1_); +} +_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (hs_empty(_set1_)) + return 1; + struct hashset_iter iter = hs_iter_start(_set1_); + for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + { + size_t value = hs_iter_value(&iter); + if (hs_impl_get_entry(_set2_, value) != ((void *)0)) + return 0; + } + return 1; +} +_Bool hs_to_string(struct hashset *_set_, FILE *fptr) +{ + struct hashset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "load:%lf, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p }", + "hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, + s_->alloc, (s_)->callbacks); +} +_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + size_t last = 0; + for (size_t i = _set_->capacity; i > 0; i--) + { + if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) + { + last = i - 1; + break; + } + } + for (size_t i = 0; i < _set_->capacity; i++) + { + struct hashset_entry *entry = &(_set_->buffer[i]); + if (entry->state == CMC_ES_FILLED) + { + if (!_set_->f_val->str(fptr, entry->value)) + return 0; + if (i + 1 < last) + fprintf(fptr, "%s", separator); + } + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_heap.c b/tests/src/tst_cmc_heap.c index 583a76e..f9af692 100644 --- a/tests/src/tst_cmc_heap.c +++ b/tests/src/tst_cmc_heap.c @@ -1,7 +1,424 @@ - #include "tst_cmc_heap.h" +#include "tst_cmc_heap.h" - - 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) { return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0)); } struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct heap *_heap_ = alloc->malloc(sizeof(struct heap)); if (!_heap_) return ((void *)0); _heap_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_heap_->buffer) { alloc->free(_heap_); return ((void *)0); } _heap_->capacity = capacity; _heap_->count = 0; _heap_->HO = HO; _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; (_heap_)->callbacks = callbacks; return _heap_; } void h_clear(struct heap * _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(size_t) * _heap_->capacity); _heap_->count = 0; _heap_->flag = CMC_FLAG_OK; } void h_free(struct heap * _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 h_customize(struct heap * _heap_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _heap_->alloc = &cmc_alloc_node_default; else _heap_->alloc = alloc; (_heap_)->callbacks = callbacks; _heap_->flag = CMC_FLAG_OK; } _Bool h_insert(struct heap * _heap_, size_t value) { if (h_full(_heap_)) { if (!h_resize(_heap_, _heap_->count * 2)) return 0; } _heap_->buffer[_heap_->count++] = value; if (_heap_->count > 1) { h_impl_float_up(_heap_, _heap_->count - 1); } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->create) (_heap_)->callbacks->create();; return 1; } _Bool h_remove(struct heap * _heap_) { if (h_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; _heap_->buffer[_heap_->count - 1] = (size_t){ 0 }; _heap_->count--; h_impl_float_down(_heap_, 0); _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->delete) (_heap_)->callbacks->delete();; return 1; } size_t h_peek(struct heap * _heap_) { if (h_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; return _heap_->buffer[0]; } _Bool h_contains(struct heap * _heap_, size_t value) { _heap_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _heap_->count; i++) { if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) { result = 1; break; } } if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; return result; } _Bool h_empty(struct heap * _heap_) { return _heap_->count == 0; } _Bool h_full(struct heap * _heap_) { return _heap_->count >= _heap_->capacity; } size_t h_count(struct heap * _heap_) { return _heap_->count; } size_t h_capacity(struct heap * _heap_) { return _heap_->capacity; } int h_flag(struct heap * _heap_) { return _heap_->flag; } _Bool h_resize(struct heap * _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 0; } size_t *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _heap_->flag = CMC_FLAG_ALLOC; return 0; } _heap_->buffer = new_buffer; _heap_->capacity = capacity; success: if ((_heap_)->callbacks && (_heap_)->callbacks->resize) (_heap_)->callbacks->resize();; return 1; } struct heap *h_copy_of(struct heap * _heap_) { struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0)); if (!result) { _heap_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _heap_->callbacks; if (_heap_->f_val->cpy) { for (size_t i = 0; i < _heap_->count; i++) result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); } else memcpy(result->buffer, _heap_->buffer, sizeof(size_t) * _heap_->count); result->count = _heap_->count; _heap_->flag = CMC_FLAG_OK; return result; } _Bool h_equals(struct heap * _heap1_, struct heap * _heap2_) { _heap1_->flag = CMC_FLAG_OK; _heap2_->flag = CMC_FLAG_OK; if (_heap1_->count != _heap2_->count) return 0; for (size_t i = 0; i < _heap1_->count; i++) { if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) return 0; } return 1; } static void h_impl_float_up(struct heap * _heap_, size_t index) { size_t C = index; size_t child = _heap_->buffer[C]; size_t parent = _heap_->buffer[(index - 1) / 2]; int mod = _heap_->HO; while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) { size_t tmp = _heap_->buffer[C]; _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; _heap_->buffer[(C - 1) / 2] = tmp; C = (C - 1) / 2; if (C == 0) break; child = _heap_->buffer[C]; parent = _heap_->buffer[(C - 1) / 2]; } } static void h_impl_float_down(struct heap * _heap_, size_t index) { int mod = _heap_->HO; while (index < _heap_->count) { size_t L = 2 * index + 1; size_t R = 2 * index + 2; size_t C = index; if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) { C = L; } if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) { C = R; } if (C != index) { size_t tmp = _heap_->buffer[index]; _heap_->buffer[index] = _heap_->buffer[C]; _heap_->buffer[C] = tmp; index = C; } else break; } } struct heap_iter h_iter_start(struct heap * target) { struct heap_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = h_empty(target); return iter; } struct heap_iter h_iter_end(struct heap * target) { struct heap_iter iter; iter.target = target; iter.cursor = 0; iter.start = h_empty(target); iter.end = 1; if (!h_empty(target)) iter.cursor = target->count - 1; return iter; } _Bool h_iter_at_start(struct heap_iter * iter) { return h_empty(iter->target) || iter->start; } _Bool h_iter_at_end(struct heap_iter * iter) { return h_empty(iter->target) || iter->end; } _Bool h_iter_to_start(struct heap_iter * iter) { if (!h_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = h_empty(iter->target); return 1; } return 0; } _Bool h_iter_to_end(struct heap_iter * iter) { if (!h_empty(iter->target)) { iter->cursor = iter->target->count - 1; iter->start = h_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool h_iter_next(struct heap_iter * iter) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = h_empty(iter->target); iter->cursor++; return 1; } _Bool h_iter_prev(struct heap_iter * iter) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } iter->end = h_empty(iter->target); iter->cursor--; return 1; } _Bool h_iter_advance(struct heap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; if (iter->end) return 0; iter->start = h_empty(iter->target); iter->cursor += steps; return 1; } _Bool h_iter_rewind(struct heap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->end = h_empty(iter->target); iter->cursor -= steps; return 1; } _Bool h_iter_go_to(struct heap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return h_iter_rewind(iter, iter->cursor - index); else if (iter->cursor < index) return h_iter_advance(iter, index - iter->cursor); return 1; } size_t h_iter_value(struct heap_iter * iter) { if (h_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t h_iter_index(struct heap_iter * iter) { return iter->cursor; } _Bool h_to_string(struct heap * _heap_, FILE * fptr) { struct heap *h_ = _heap_; const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "type:%s, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks: %p}", "heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, (h_)->callbacks); } _Bool h_print(struct heap * _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 0; if (i + 1 < _heap_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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) +{ + return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0)); +} +struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, + struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (capacity < 1) + return ((void *)0); + if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) + return ((void *)0); + if (!f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct heap *_heap_ = alloc->malloc(sizeof(struct heap)); + if (!_heap_) + return ((void *)0); + _heap_->buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_heap_->buffer) + { + alloc->free(_heap_); + return ((void *)0); + } + _heap_->capacity = capacity; + _heap_->count = 0; + _heap_->HO = HO; + _heap_->flag = CMC_FLAG_OK; + _heap_->f_val = f_val; + _heap_->alloc = alloc; + (_heap_)->callbacks = callbacks; + return _heap_; +} +void h_clear(struct heap *_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(size_t) * _heap_->capacity); + _heap_->count = 0; + _heap_->flag = CMC_FLAG_OK; +} +void h_free(struct heap *_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 h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _heap_->alloc = &cmc_alloc_node_default; + else + _heap_->alloc = alloc; + (_heap_)->callbacks = callbacks; + _heap_->flag = CMC_FLAG_OK; +} +_Bool h_insert(struct heap *_heap_, size_t value) +{ + if (h_full(_heap_)) + { + if (!h_resize(_heap_, _heap_->count * 2)) + return 0; + } + _heap_->buffer[_heap_->count++] = value; + if (_heap_->count > 1) + { + h_impl_float_up(_heap_, _heap_->count - 1); + } + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->create) + (_heap_)->callbacks->create(); + ; + return 1; +} +_Bool h_remove(struct heap *_heap_) +{ + if (h_empty(_heap_)) + { + _heap_->flag = CMC_FLAG_EMPTY; + return 0; + } + _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; + _heap_->buffer[_heap_->count - 1] = (size_t){ 0 }; + _heap_->count--; + h_impl_float_down(_heap_, 0); + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; + return 1; +} +size_t h_peek(struct heap *_heap_) +{ + if (h_empty(_heap_)) + { + _heap_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; + return _heap_->buffer[0]; +} +_Bool h_contains(struct heap *_heap_, size_t value) +{ + _heap_->flag = CMC_FLAG_OK; + _Bool result = 0; + for (size_t i = 0; i < _heap_->count; i++) + { + if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) + { + result = 1; + break; + } + } + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; + return result; +} +_Bool h_empty(struct heap *_heap_) +{ + return _heap_->count == 0; +} +_Bool h_full(struct heap *_heap_) +{ + return _heap_->count >= _heap_->capacity; +} +size_t h_count(struct heap *_heap_) +{ + return _heap_->count; +} +size_t h_capacity(struct heap *_heap_) +{ + return _heap_->capacity; +} +int h_flag(struct heap *_heap_) +{ + return _heap_->flag; +} +_Bool h_resize(struct heap *_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 0; + } + size_t *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity); + if (!new_buffer) + { + _heap_->flag = CMC_FLAG_ALLOC; + return 0; + } + _heap_->buffer = new_buffer; + _heap_->capacity = capacity; +success: + if ((_heap_)->callbacks && (_heap_)->callbacks->resize) + (_heap_)->callbacks->resize(); + ; + return 1; +} +struct heap *h_copy_of(struct heap *_heap_) +{ + struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0)); + if (!result) + { + _heap_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _heap_->callbacks; + if (_heap_->f_val->cpy) + { + for (size_t i = 0; i < _heap_->count; i++) + result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); + } + else + memcpy(result->buffer, _heap_->buffer, sizeof(size_t) * _heap_->count); + result->count = _heap_->count; + _heap_->flag = CMC_FLAG_OK; + return result; +} +_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_) +{ + _heap1_->flag = CMC_FLAG_OK; + _heap2_->flag = CMC_FLAG_OK; + if (_heap1_->count != _heap2_->count) + return 0; + for (size_t i = 0; i < _heap1_->count; i++) + { + if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) + return 0; + } + return 1; +} +static void h_impl_float_up(struct heap *_heap_, size_t index) +{ + size_t C = index; + size_t child = _heap_->buffer[C]; + size_t parent = _heap_->buffer[(index - 1) / 2]; + int mod = _heap_->HO; + while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) + { + size_t tmp = _heap_->buffer[C]; + _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; + _heap_->buffer[(C - 1) / 2] = tmp; + C = (C - 1) / 2; + if (C == 0) + break; + child = _heap_->buffer[C]; + parent = _heap_->buffer[(C - 1) / 2]; + } +} +static void h_impl_float_down(struct heap *_heap_, size_t index) +{ + int mod = _heap_->HO; + while (index < _heap_->count) + { + size_t L = 2 * index + 1; + size_t R = 2 * index + 2; + size_t C = index; + if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) + { + C = L; + } + if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) + { + C = R; + } + if (C != index) + { + size_t tmp = _heap_->buffer[index]; + _heap_->buffer[index] = _heap_->buffer[C]; + _heap_->buffer[C] = tmp; + index = C; + } + else + break; + } +} +struct heap_iter h_iter_start(struct heap *target) +{ + struct heap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = h_empty(target); + return iter; +} +struct heap_iter h_iter_end(struct heap *target) +{ + struct heap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = h_empty(target); + iter.end = 1; + if (!h_empty(target)) + iter.cursor = target->count - 1; + return iter; +} +_Bool h_iter_at_start(struct heap_iter *iter) +{ + return h_empty(iter->target) || iter->start; +} +_Bool h_iter_at_end(struct heap_iter *iter) +{ + return h_empty(iter->target) || iter->end; +} +_Bool h_iter_to_start(struct heap_iter *iter) +{ + if (!h_empty(iter->target)) + { + iter->cursor = 0; + iter->start = 1; + iter->end = h_empty(iter->target); + return 1; + } + return 0; +} +_Bool h_iter_to_end(struct heap_iter *iter) +{ + if (!h_empty(iter->target)) + { + iter->cursor = iter->target->count - 1; + iter->start = h_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool h_iter_next(struct heap_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = h_empty(iter->target); + iter->cursor++; + return 1; +} +_Bool h_iter_prev(struct heap_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + iter->end = h_empty(iter->target); + iter->cursor--; + return 1; +} +_Bool h_iter_advance(struct heap_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return 0; + if (iter->end) + return 0; + iter->start = h_empty(iter->target); + iter->cursor += steps; + return 1; +} +_Bool h_iter_rewind(struct heap_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->cursor < steps) + return 0; + iter->end = h_empty(iter->target); + iter->cursor -= steps; + return 1; +} +_Bool h_iter_go_to(struct heap_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->cursor > index) + return h_iter_rewind(iter, iter->cursor - index); + else if (iter->cursor < index) + return h_iter_advance(iter, index - iter->cursor); + return 1; +} +size_t h_iter_value(struct heap_iter *iter) +{ + if (h_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor]; +} +size_t h_iter_index(struct heap_iter *iter) +{ + return iter->cursor; +} +_Bool h_to_string(struct heap *_heap_, FILE *fptr) +{ + struct heap *h_ = _heap_; + const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "type:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks: %p}", + "heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, + (h_)->callbacks); +} +_Bool h_print(struct heap *_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 0; + if (i + 1 < _heap_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_intervalheap.c b/tests/src/tst_cmc_intervalheap.c index 38d680c..e83970e 100644 --- a/tests/src/tst_cmc_intervalheap.c +++ b/tests/src/tst_cmc_intervalheap.c @@ -1,7 +1,686 @@ - #include "tst_cmc_intervalheap.h" +#include "tst_cmc_intervalheap.h" - - static void ih_impl_float_up_max(struct intervalheap * _heap_); static void ih_impl_float_up_min(struct intervalheap * _heap_); static void ih_impl_float_down_max(struct intervalheap * _heap_); static void ih_impl_float_down_min(struct intervalheap * _heap_); struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval * f_val) { return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity == 0 || capacity == 0xffffffffffffffffULL) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap)); if (!_heap_) return ((void *)0); capacity = (capacity + capacity % 2) / 2; _heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2])); if (!_heap_->buffer) { alloc->free(_heap_); return ((void *)0); } _heap_->capacity = capacity; _heap_->size = 0; _heap_->count = 0; _heap_->flag = CMC_FLAG_OK; _heap_->f_val = f_val; _heap_->alloc = alloc; (_heap_)->callbacks = callbacks; return _heap_; } void ih_clear(struct intervalheap * _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(size_t[2]) * _heap_->capacity); _heap_->size = 0; _heap_->count = 0; _heap_->flag = CMC_FLAG_OK; } void ih_free(struct intervalheap * _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 ih_customize(struct intervalheap * _heap_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _heap_->alloc = &cmc_alloc_node_default; else _heap_->alloc = alloc; (_heap_)->callbacks = callbacks; _heap_->flag = CMC_FLAG_OK; } _Bool ih_insert(struct intervalheap * _heap_, size_t value) { if (ih_full(_heap_)) { if (!ih_resize(_heap_, _heap_->capacity * 4)) return 0; } if (_heap_->count % 2 == 0) { _heap_->buffer[_heap_->size][0] = value; _heap_->buffer[_heap_->size][1] = (size_t){ 0 }; _heap_->size++; } else { size_t(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); if (_heap_->f_val->cmp((*node)[0], value) > 0) { (*node)[1] = (*node)[0]; (*node)[0] = value; } else { (*node)[1] = value; } } _heap_->count++; _heap_->flag = CMC_FLAG_OK; if (_heap_->count > 2) { size_t(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); if (_heap_->f_val->cmp((*parent)[0], value) > 0) ih_impl_float_up_min(_heap_); else if (_heap_->f_val->cmp((*parent)[1], value) < 0) ih_impl_float_up_max(_heap_); } if ((_heap_)->callbacks && (_heap_)->callbacks->create) (_heap_)->callbacks->create();; return 1; } _Bool ih_remove_max(struct intervalheap * _heap_) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) { _heap_->buffer[0][0] = (size_t){ 0 }; _heap_->count--; _heap_->size--; goto success; } size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); if (_heap_->count % 2 == 1) { _heap_->buffer[0][1] = (*last_node)[0]; (*last_node)[0] = (size_t){ 0 }; _heap_->size--; } else { _heap_->buffer[0][1] = (*last_node)[1]; (*last_node)[1] = (size_t){ 0 }; } _heap_->count--; ih_impl_float_down_max(_heap_); success: _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->delete) (_heap_)->callbacks->delete();; return 1; } _Bool ih_remove_min(struct intervalheap * _heap_) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) { _heap_->buffer[0][0] = (size_t){ 0 }; _heap_->count--; _heap_->size--; goto success; } size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); _heap_->buffer[0][0] = (*last_node)[0]; if (_heap_->count % 2 == 1) { (*last_node)[0] = (size_t){ 0 }; _heap_->size--; } else { (*last_node)[0] = (*last_node)[1]; (*last_node)[1] = (size_t){ 0 }; } _heap_->count--; ih_impl_float_down_min(_heap_); success: _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->delete) (_heap_)->callbacks->delete();; return 1; } _Bool ih_update_max(struct intervalheap * _heap_, size_t value) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) { _heap_->buffer[0][0] = value; } else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0) { _heap_->buffer[0][1] = _heap_->buffer[0][0]; _heap_->buffer[0][0] = value; ih_impl_float_down_max(_heap_); } else { _heap_->buffer[0][1] = value; ih_impl_float_down_max(_heap_); } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->update) (_heap_)->callbacks->update();; return 1; } _Bool ih_update_min(struct intervalheap * _heap_, size_t value) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return 0; } if (_heap_->count == 1) { _heap_->buffer[0][0] = value; } else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) { _heap_->buffer[0][0] = _heap_->buffer[0][1]; _heap_->buffer[0][1] = value; ih_impl_float_down_min(_heap_); } else { _heap_->buffer[0][0] = value; ih_impl_float_down_min(_heap_); } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->update) (_heap_)->callbacks->update();; return 1; } size_t ih_max(struct intervalheap * _heap_) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; if (_heap_->count == 1) return _heap_->buffer[0][0]; return _heap_->buffer[0][1]; } size_t ih_min(struct intervalheap * _heap_) { if (ih_empty(_heap_)) { _heap_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _heap_->flag = CMC_FLAG_OK; if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; return _heap_->buffer[0][0]; } _Bool ih_contains(struct intervalheap * _heap_, size_t value) { _heap_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _heap_->count; i++) { if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0) { result = 1; break; } } if ((_heap_)->callbacks && (_heap_)->callbacks->read) (_heap_)->callbacks->read();; return result; } _Bool ih_empty(struct intervalheap * _heap_) { return _heap_->count == 0; } _Bool ih_full(struct intervalheap * _heap_) { return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; } size_t ih_count(struct intervalheap * _heap_) { return _heap_->count; } size_t ih_capacity(struct intervalheap * _heap_) { return _heap_->capacity; } int ih_flag(struct intervalheap * _heap_) { return _heap_->flag; } _Bool ih_resize(struct intervalheap * _heap_, size_t capacity) { if (_heap_->capacity == capacity) goto success; if (capacity < _heap_->count) { _heap_->flag = CMC_FLAG_INVALID; return 0; } if (capacity == 0xffffffffffffffffULL) { _heap_->flag = CMC_FLAG_ERROR; return 0; } capacity += capacity % 2; size_t(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity); if (!new_buffer) { _heap_->flag = CMC_FLAG_ALLOC; return 0; } if (capacity > _heap_->capacity) { memset(new_buffer + _heap_->capacity, 0, sizeof(size_t[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 1; } struct intervalheap *ih_copy_of(struct intervalheap * _heap_) { 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); if (!result->buffer) { _heap_->alloc->free(result); _heap_->flag = CMC_FLAG_ALLOC; return ((void *)0); } 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(size_t[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 ih_equals(struct intervalheap * _heap1_, struct intervalheap * _heap2_) { _heap1_->flag = CMC_FLAG_OK; _heap2_->flag = CMC_FLAG_OK; if (_heap1_->count != _heap2_->count) return 0; for (size_t i = 0; i < _heap1_->count; i++) { size_t value1 = _heap1_->buffer[i / 2][i % 2]; size_t value2 = _heap2_->buffer[i / 2][i % 2]; if (_heap1_->f_val->cmp(value1, value2) != 0) return 0; } return 1; } static void ih_impl_float_up_max(struct intervalheap * _heap_) { size_t index = _heap_->size - 1; size_t(*curr_node)[2] = &(_heap_->buffer[index]); while (index > 0) { size_t P_index = (index - 1) / 2; size_t(*parent)[2] = &(_heap_->buffer[P_index]); if (index == _heap_->size - 1 && _heap_->count % 2 != 0) { if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0) break; size_t tmp = (*curr_node)[0]; (*curr_node)[0] = (*parent)[1]; (*parent)[1] = tmp; } else { if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0) break; size_t tmp = (*curr_node)[1]; (*curr_node)[1] = (*parent)[1]; (*parent)[1] = tmp; } index = P_index; curr_node = parent; } } static void ih_impl_float_up_min(struct intervalheap * _heap_) { size_t index = _heap_->size - 1; size_t(*curr_node)[2] = &(_heap_->buffer[index]); while (index > 0) { size_t P_index = (index - 1) / 2; size_t(*parent)[2] = &(_heap_->buffer[P_index]); if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) break; size_t tmp = (*curr_node)[0]; (*curr_node)[0] = (*parent)[0]; (*parent)[0] = tmp; index = P_index; curr_node = parent; } } static void ih_impl_float_down_max(struct intervalheap * _heap_) { size_t index = 0; size_t(*curr_node)[2] = &(_heap_->buffer[index]); while (1) { if (2 * index + 1 >= _heap_->size) break; size_t child; size_t L_index = index * 2 + 1; size_t R_index = index * 2 + 2; if (R_index < _heap_->size) { 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; else child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index; } else child = L_index; size_t(*child_node)[2] = &(_heap_->buffer[child]); if (child == _heap_->size - 1 && _heap_->count % 2 != 0) { if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0) break; size_t tmp = (*child_node)[0]; (*child_node)[0] = (*curr_node)[1]; (*curr_node)[1] = tmp; } else { if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0) break; size_t tmp = (*child_node)[1]; (*child_node)[1] = (*curr_node)[1]; (*curr_node)[1] = tmp; if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) { tmp = (*child_node)[0]; (*child_node)[0] = (*child_node)[1]; (*child_node)[1] = tmp; } } index = child; curr_node = child_node; } } static void ih_impl_float_down_min(struct intervalheap * _heap_) { size_t index = 0; size_t(*curr_node)[2] = &(_heap_->buffer[index]); while (1) { if (2 * index + 1 >= _heap_->size) break; size_t child; size_t L_index = index * 2 + 1; size_t R_index = index * 2 + 2; if (R_index < _heap_->size) { 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; } else child = L_index; size_t(*child_node)[2] = &(_heap_->buffer[child]); if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) break; size_t tmp = (*child_node)[0]; (*child_node)[0] = (*curr_node)[0]; (*curr_node)[0] = tmp; if (child != _heap_->size - 1 || _heap_->count % 2 == 0) { if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) { tmp = (*child_node)[0]; (*child_node)[0] = (*child_node)[1]; (*child_node)[1] = tmp; } } index = child; curr_node = child_node; } } struct intervalheap_iter ih_iter_start(struct intervalheap * target) { struct intervalheap_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = ih_empty(target); return iter; } struct intervalheap_iter ih_iter_end(struct intervalheap * target) { struct intervalheap_iter iter; iter.target = target; iter.cursor = 0; iter.start = ih_empty(target); iter.end = 1; if (!ih_empty(target)) iter.cursor = target->count - 1; return iter; } _Bool ih_iter_at_start(struct intervalheap_iter * iter) { return ih_empty(iter->target) || iter->start; } _Bool ih_iter_at_end(struct intervalheap_iter * iter) { return ih_empty(iter->target) || iter->end; } _Bool ih_iter_to_start(struct intervalheap_iter * iter) { if (!ih_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = ih_empty(iter->target); return 1; } return 0; } _Bool ih_iter_to_end(struct intervalheap_iter * iter) { if (!ih_empty(iter->target)) { iter->cursor = iter->target->count - 1; iter->start = ih_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool ih_iter_next(struct intervalheap_iter * iter) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = ih_empty(iter->target); iter->cursor++; return 1; } _Bool ih_iter_prev(struct intervalheap_iter * iter) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } iter->end = ih_empty(iter->target); iter->cursor--; return 1; } _Bool ih_iter_advance(struct intervalheap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; if (iter->end) return 0; iter->start = ih_empty(iter->target); iter->cursor += steps; return 1; } _Bool ih_iter_rewind(struct intervalheap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->end = ih_empty(iter->target); iter->cursor -= steps; return 1; } _Bool ih_iter_go_to(struct intervalheap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return ih_iter_rewind(iter, iter->cursor - index); else if (iter->cursor < index) return ih_iter_advance(iter, index - iter->cursor); return 1; } size_t ih_iter_value(struct intervalheap_iter * iter) { if (ih_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; } size_t ih_iter_index(struct intervalheap_iter * iter) { return iter->cursor; } _Bool ih_to_string(struct intervalheap * _heap_, FILE * fptr) { struct intervalheap *h_ = _heap_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "size:%" "I64u" ", " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, h_->f_val, h_->alloc, (h_)->callbacks); } _Bool ih_print(struct intervalheap * _heap_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = 0; i < _heap_->count; i++) { if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) return 0; if (i + 1 < _heap_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +static void ih_impl_float_up_max(struct intervalheap *_heap_); +static void ih_impl_float_up_min(struct intervalheap *_heap_); +static void ih_impl_float_down_max(struct intervalheap *_heap_); +static void ih_impl_float_down_min(struct intervalheap *_heap_); +struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) +{ + return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0)); +} +struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (capacity == 0 || capacity == 0xffffffffffffffffULL) + return ((void *)0); + if (!f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap)); + if (!_heap_) + return ((void *)0); + capacity = (capacity + capacity % 2) / 2; + _heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2])); + if (!_heap_->buffer) + { + alloc->free(_heap_); + return ((void *)0); + } + _heap_->capacity = capacity; + _heap_->size = 0; + _heap_->count = 0; + _heap_->flag = CMC_FLAG_OK; + _heap_->f_val = f_val; + _heap_->alloc = alloc; + (_heap_)->callbacks = callbacks; + return _heap_; +} +void ih_clear(struct intervalheap *_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(size_t[2]) * _heap_->capacity); + _heap_->size = 0; + _heap_->count = 0; + _heap_->flag = CMC_FLAG_OK; +} +void ih_free(struct intervalheap *_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 ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _heap_->alloc = &cmc_alloc_node_default; + else + _heap_->alloc = alloc; + (_heap_)->callbacks = callbacks; + _heap_->flag = CMC_FLAG_OK; +} +_Bool ih_insert(struct intervalheap *_heap_, size_t value) +{ + if (ih_full(_heap_)) + { + if (!ih_resize(_heap_, _heap_->capacity * 4)) + return 0; + } + if (_heap_->count % 2 == 0) + { + _heap_->buffer[_heap_->size][0] = value; + _heap_->buffer[_heap_->size][1] = (size_t){ 0 }; + _heap_->size++; + } + else + { + size_t(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); + if (_heap_->f_val->cmp((*node)[0], value) > 0) + { + (*node)[1] = (*node)[0]; + (*node)[0] = value; + } + else + { + (*node)[1] = value; + } + } + _heap_->count++; + _heap_->flag = CMC_FLAG_OK; + if (_heap_->count > 2) + { + size_t(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); + if (_heap_->f_val->cmp((*parent)[0], value) > 0) + ih_impl_float_up_min(_heap_); + else if (_heap_->f_val->cmp((*parent)[1], value) < 0) + ih_impl_float_up_max(_heap_); + } + if ((_heap_)->callbacks && (_heap_)->callbacks->create) + (_heap_)->callbacks->create(); + ; + return 1; +} +_Bool ih_remove_max(struct intervalheap *_heap_) +{ + if (ih_empty(_heap_)) + { + _heap_->flag = CMC_FLAG_EMPTY; + return 0; + } + if (_heap_->count == 1) + { + _heap_->buffer[0][0] = (size_t){ 0 }; + _heap_->count--; + _heap_->size--; + goto success; + } + size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); + if (_heap_->count % 2 == 1) + { + _heap_->buffer[0][1] = (*last_node)[0]; + (*last_node)[0] = (size_t){ 0 }; + _heap_->size--; + } + else + { + _heap_->buffer[0][1] = (*last_node)[1]; + (*last_node)[1] = (size_t){ 0 }; + } + _heap_->count--; + ih_impl_float_down_max(_heap_); +success: + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; + return 1; +} +_Bool ih_remove_min(struct intervalheap *_heap_) +{ + if (ih_empty(_heap_)) + { + _heap_->flag = CMC_FLAG_EMPTY; + return 0; + } + if (_heap_->count == 1) + { + _heap_->buffer[0][0] = (size_t){ 0 }; + _heap_->count--; + _heap_->size--; + goto success; + } + size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); + _heap_->buffer[0][0] = (*last_node)[0]; + if (_heap_->count % 2 == 1) + { + (*last_node)[0] = (size_t){ 0 }; + _heap_->size--; + } + else + { + (*last_node)[0] = (*last_node)[1]; + (*last_node)[1] = (size_t){ 0 }; + } + _heap_->count--; + ih_impl_float_down_min(_heap_); +success: + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->delete) + (_heap_)->callbacks->delete (); + ; + return 1; +} +_Bool ih_update_max(struct intervalheap *_heap_, size_t value) +{ + if (ih_empty(_heap_)) + { + _heap_->flag = CMC_FLAG_EMPTY; + return 0; + } + if (_heap_->count == 1) + { + _heap_->buffer[0][0] = value; + } + else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0) + { + _heap_->buffer[0][1] = _heap_->buffer[0][0]; + _heap_->buffer[0][0] = value; + ih_impl_float_down_max(_heap_); + } + else + { + _heap_->buffer[0][1] = value; + ih_impl_float_down_max(_heap_); + } + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->update) + (_heap_)->callbacks->update(); + ; + return 1; +} +_Bool ih_update_min(struct intervalheap *_heap_, size_t value) +{ + if (ih_empty(_heap_)) + { + _heap_->flag = CMC_FLAG_EMPTY; + return 0; + } + if (_heap_->count == 1) + { + _heap_->buffer[0][0] = value; + } + else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) + { + _heap_->buffer[0][0] = _heap_->buffer[0][1]; + _heap_->buffer[0][1] = value; + ih_impl_float_down_min(_heap_); + } + else + { + _heap_->buffer[0][0] = value; + ih_impl_float_down_min(_heap_); + } + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->update) + (_heap_)->callbacks->update(); + ; + return 1; +} +size_t ih_max(struct intervalheap *_heap_) +{ + if (ih_empty(_heap_)) + { + _heap_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; + if (_heap_->count == 1) + return _heap_->buffer[0][0]; + return _heap_->buffer[0][1]; +} +size_t ih_min(struct intervalheap *_heap_) +{ + if (ih_empty(_heap_)) + { + _heap_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _heap_->flag = CMC_FLAG_OK; + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; + return _heap_->buffer[0][0]; +} +_Bool ih_contains(struct intervalheap *_heap_, size_t value) +{ + _heap_->flag = CMC_FLAG_OK; + _Bool result = 0; + for (size_t i = 0; i < _heap_->count; i++) + { + if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0) + { + result = 1; + break; + } + } + if ((_heap_)->callbacks && (_heap_)->callbacks->read) + (_heap_)->callbacks->read(); + ; + return result; +} +_Bool ih_empty(struct intervalheap *_heap_) +{ + return _heap_->count == 0; +} +_Bool ih_full(struct intervalheap *_heap_) +{ + return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; +} +size_t ih_count(struct intervalheap *_heap_) +{ + return _heap_->count; +} +size_t ih_capacity(struct intervalheap *_heap_) +{ + return _heap_->capacity; +} +int ih_flag(struct intervalheap *_heap_) +{ + return _heap_->flag; +} +_Bool ih_resize(struct intervalheap *_heap_, size_t capacity) +{ + if (_heap_->capacity == capacity) + goto success; + if (capacity < _heap_->count) + { + _heap_->flag = CMC_FLAG_INVALID; + return 0; + } + if (capacity == 0xffffffffffffffffULL) + { + _heap_->flag = CMC_FLAG_ERROR; + return 0; + } + capacity += capacity % 2; + size_t(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity); + if (!new_buffer) + { + _heap_->flag = CMC_FLAG_ALLOC; + return 0; + } + if (capacity > _heap_->capacity) + { + memset(new_buffer + _heap_->capacity, 0, sizeof(size_t[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 1; +} +struct intervalheap *ih_copy_of(struct intervalheap *_heap_) +{ + 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); + if (!result->buffer) + { + _heap_->alloc->free(result); + _heap_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + 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(size_t[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 ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_) +{ + _heap1_->flag = CMC_FLAG_OK; + _heap2_->flag = CMC_FLAG_OK; + if (_heap1_->count != _heap2_->count) + return 0; + for (size_t i = 0; i < _heap1_->count; i++) + { + size_t value1 = _heap1_->buffer[i / 2][i % 2]; + size_t value2 = _heap2_->buffer[i / 2][i % 2]; + if (_heap1_->f_val->cmp(value1, value2) != 0) + return 0; + } + return 1; +} +static void ih_impl_float_up_max(struct intervalheap *_heap_) +{ + size_t index = _heap_->size - 1; + size_t(*curr_node)[2] = &(_heap_->buffer[index]); + while (index > 0) + { + size_t P_index = (index - 1) / 2; + size_t(*parent)[2] = &(_heap_->buffer[P_index]); + if (index == _heap_->size - 1 && _heap_->count % 2 != 0) + { + if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0) + break; + size_t tmp = (*curr_node)[0]; + (*curr_node)[0] = (*parent)[1]; + (*parent)[1] = tmp; + } + else + { + if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0) + break; + size_t tmp = (*curr_node)[1]; + (*curr_node)[1] = (*parent)[1]; + (*parent)[1] = tmp; + } + index = P_index; + curr_node = parent; + } +} +static void ih_impl_float_up_min(struct intervalheap *_heap_) +{ + size_t index = _heap_->size - 1; + size_t(*curr_node)[2] = &(_heap_->buffer[index]); + while (index > 0) + { + size_t P_index = (index - 1) / 2; + size_t(*parent)[2] = &(_heap_->buffer[P_index]); + if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) + break; + size_t tmp = (*curr_node)[0]; + (*curr_node)[0] = (*parent)[0]; + (*parent)[0] = tmp; + index = P_index; + curr_node = parent; + } +} +static void ih_impl_float_down_max(struct intervalheap *_heap_) +{ + size_t index = 0; + size_t(*curr_node)[2] = &(_heap_->buffer[index]); + while (1) + { + if (2 * index + 1 >= _heap_->size) + break; + size_t child; + size_t L_index = index * 2 + 1; + size_t R_index = index * 2 + 2; + if (R_index < _heap_->size) + { + 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; + else + child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index; + } + else + child = L_index; + size_t(*child_node)[2] = &(_heap_->buffer[child]); + if (child == _heap_->size - 1 && _heap_->count % 2 != 0) + { + if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0) + break; + size_t tmp = (*child_node)[0]; + (*child_node)[0] = (*curr_node)[1]; + (*curr_node)[1] = tmp; + } + else + { + if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0) + break; + size_t tmp = (*child_node)[1]; + (*child_node)[1] = (*curr_node)[1]; + (*curr_node)[1] = tmp; + if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) + { + tmp = (*child_node)[0]; + (*child_node)[0] = (*child_node)[1]; + (*child_node)[1] = tmp; + } + } + index = child; + curr_node = child_node; + } +} +static void ih_impl_float_down_min(struct intervalheap *_heap_) +{ + size_t index = 0; + size_t(*curr_node)[2] = &(_heap_->buffer[index]); + while (1) + { + if (2 * index + 1 >= _heap_->size) + break; + size_t child; + size_t L_index = index * 2 + 1; + size_t R_index = index * 2 + 2; + if (R_index < _heap_->size) + { + 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; + } + else + child = L_index; + size_t(*child_node)[2] = &(_heap_->buffer[child]); + if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) + break; + size_t tmp = (*child_node)[0]; + (*child_node)[0] = (*curr_node)[0]; + (*curr_node)[0] = tmp; + if (child != _heap_->size - 1 || _heap_->count % 2 == 0) + { + if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) + { + tmp = (*child_node)[0]; + (*child_node)[0] = (*child_node)[1]; + (*child_node)[1] = tmp; + } + } + index = child; + curr_node = child_node; + } +} +struct intervalheap_iter ih_iter_start(struct intervalheap *target) +{ + struct intervalheap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = ih_empty(target); + return iter; +} +struct intervalheap_iter ih_iter_end(struct intervalheap *target) +{ + struct intervalheap_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = ih_empty(target); + iter.end = 1; + if (!ih_empty(target)) + iter.cursor = target->count - 1; + return iter; +} +_Bool ih_iter_at_start(struct intervalheap_iter *iter) +{ + return ih_empty(iter->target) || iter->start; +} +_Bool ih_iter_at_end(struct intervalheap_iter *iter) +{ + return ih_empty(iter->target) || iter->end; +} +_Bool ih_iter_to_start(struct intervalheap_iter *iter) +{ + if (!ih_empty(iter->target)) + { + iter->cursor = 0; + iter->start = 1; + iter->end = ih_empty(iter->target); + return 1; + } + return 0; +} +_Bool ih_iter_to_end(struct intervalheap_iter *iter) +{ + if (!ih_empty(iter->target)) + { + iter->cursor = iter->target->count - 1; + iter->start = ih_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool ih_iter_next(struct intervalheap_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = ih_empty(iter->target); + iter->cursor++; + return 1; +} +_Bool ih_iter_prev(struct intervalheap_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + iter->end = ih_empty(iter->target); + iter->cursor--; + return 1; +} +_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return 0; + if (iter->end) + return 0; + iter->start = ih_empty(iter->target); + iter->cursor += steps; + return 1; +} +_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->cursor < steps) + return 0; + iter->end = ih_empty(iter->target); + iter->cursor -= steps; + return 1; +} +_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->cursor > index) + return ih_iter_rewind(iter, iter->cursor - index); + else if (iter->cursor < index) + return ih_iter_advance(iter, index - iter->cursor); + return 1; +} +size_t ih_iter_value(struct intervalheap_iter *iter) +{ + if (ih_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; +} +size_t ih_iter_index(struct intervalheap_iter *iter) +{ + return iter->cursor; +} +_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr) +{ + struct intervalheap *h_ = _heap_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "size:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, + h_->f_val, h_->alloc, (h_)->callbacks); +} +_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _heap_->count; i++) + { + if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) + return 0; + if (i + 1 < _heap_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_linkedlist.c b/tests/src/tst_cmc_linkedlist.c index cbf5a65..2587108 100644 --- a/tests/src/tst_cmc_linkedlist.c +++ b/tests/src/tst_cmc_linkedlist.c @@ -1,7 +1,683 @@ - #include "tst_cmc_linkedlist.h" +#include "tst_cmc_linkedlist.h" - - struct linkedlist *ll_new(struct linkedlist_fval * f_val) { return ll_new_custom(f_val, ((void *)0), ((void *)0)); } struct linkedlist *ll_new_custom(struct linkedlist_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist)); if (!_list_) return ((void *)0); _list_->count = 0; _list_->head = ((void *)0); _list_->tail = ((void *)0); _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; (_list_)->callbacks = callbacks; return _list_; } void ll_clear(struct linkedlist * _list_) { struct linkedlist_node *scan = _list_->head; while (_list_->head != ((void *)0)) { _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 = ((void *)0); _list_->tail = ((void *)0); _list_->flag = CMC_FLAG_OK; } 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) { ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool ll_push_front(struct linkedlist * _list_, size_t value) { struct linkedlist_node *_node_ = ll_new_node(_list_, value); if (!_node_) return 0; if (ll_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 1; } _Bool ll_push_at(struct linkedlist * _list_, size_t value, size_t index) { if (index > _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) { return ll_push_front(_list_, value); } else if (index == _list_->count) { return ll_push_back(_list_, value); } struct linkedlist_node *_node_ = ll_new_node(_list_, value); if (!_node_) return 0; struct linkedlist_node *scan = ll_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 1; } _Bool ll_push_back(struct linkedlist * _list_, size_t value) { struct linkedlist_node *_node_ = ll_new_node(_list_, value); if (!_node_) return 0; if (ll_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 1; } _Bool ll_pop_front(struct linkedlist * _list_) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } struct linkedlist_node *_node_ = _list_->head; _list_->head = _list_->head->next; _list_->alloc->free(_node_); if (_list_->head == ((void *)0)) _list_->tail = ((void *)0); else _list_->head->prev = ((void *)0); _list_->count--; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } _Bool ll_pop_at(struct linkedlist * _list_, size_t index) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) { return ll_pop_front(_list_); } else if (index == _list_->count - 1) { return ll_pop_back(_list_); } struct linkedlist_node *_node_ = ll_get_node(_list_, index); if (!_node_) return 0; _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 1; } _Bool ll_pop_back(struct linkedlist * _list_) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } struct linkedlist_node *_node_ = _list_->tail; _list_->tail = _list_->tail->prev; _list_->alloc->free(_node_); if (_list_->tail == ((void *)0)) _list_->head = ((void *)0); else _list_->tail->next = ((void *)0); _list_->count--; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } size_t ll_front(struct linkedlist * _list_) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->head->value; } size_t ll_get(struct linkedlist * _list_, size_t index) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } struct linkedlist_node *scan = ll_get_node(_list_, index); if (scan == ((void *)0)) return (size_t){ 0 }; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return scan->value; } size_t *ll_get_ref(struct linkedlist * _list_, size_t index) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } struct linkedlist_node *scan = ll_get_node(_list_, index); if (scan == ((void *)0)) return ((void *)0); if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return &(scan->value); } size_t ll_back(struct linkedlist * _list_) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->tail->value; } _Bool ll_contains(struct linkedlist * _list_, size_t value) { _list_->flag = CMC_FLAG_OK; _Bool result = 0; struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) { if (_list_->f_val->cmp(scan->value, value) == 0) { result = 1; break; } scan = scan->next; } if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return result; } _Bool ll_empty(struct linkedlist * _list_) { return _list_->count == 0; } size_t ll_count(struct linkedlist * _list_) { return _list_->count; } int ll_flag(struct linkedlist * _list_) { return _list_->flag; } struct linkedlist *ll_copy_of(struct linkedlist * _list_) { struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0)); if (!result) return ((void *)0); (result)->callbacks = _list_->callbacks; struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) { struct linkedlist_node * new_node; if (_list_->f_val->cpy) new_node = ll_new_node(_list_, _list_->f_val->cpy(scan->value)); else new_node = ll_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 ll_equals(struct linkedlist * _list1_, struct linkedlist * _list2_) { _list1_->flag = CMC_FLAG_OK; _list2_->flag = CMC_FLAG_OK; if (_list1_->count != _list2_->count) return 0; struct linkedlist_node *scan1 = _list1_->head; struct linkedlist_node *scan2 = _list2_->head; while (scan1 != ((void *)0) && scan2 != ((void *)0)) { if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) return 0; scan1 = scan1->next; scan2 = scan2->next; } return 1; } struct linkedlist_iter ll_iter_start(struct linkedlist * target) { struct linkedlist_iter iter; iter.target = target; iter.cursor = target->head; iter.index = 0; iter.start = 1; iter.end = ll_empty(target); return iter; } struct linkedlist_iter ll_iter_end(struct linkedlist * target) { struct linkedlist_iter iter; iter.target = target; iter.cursor = target->tail; iter.index = 0; iter.start = ll_empty(target); iter.end = 1; if (!ll_empty(target)) iter.index = target->count - 1; return iter; } _Bool ll_iter_at_start(struct linkedlist_iter * iter) { return ll_empty(iter->target) || iter->start; } _Bool ll_iter_at_end(struct linkedlist_iter * iter) { return ll_empty(iter->target) || iter->end; } _Bool ll_iter_to_start(struct linkedlist_iter * iter) { if (!ll_empty(iter->target)) { iter->cursor = iter->target->head; iter->index = 0; iter->start = 1; iter->end = ll_empty(iter->target); return 1; } return 0; } _Bool ll_iter_to_end(struct linkedlist_iter * iter) { if (!ll_empty(iter->target)) { iter->cursor = iter->target->tail; iter->index = iter->target->count - 1; iter->start = ll_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool ll_iter_next(struct linkedlist_iter * iter) { if (iter->end) return 0; if (iter->cursor->next == ((void *)0)) { iter->end = 1; return 0; } iter->start = ll_empty(iter->target); iter->cursor = iter->cursor->next; iter->index++; return 1; } _Bool ll_iter_prev(struct linkedlist_iter * iter) { if (iter->start) return 0; if (iter->cursor->prev == ((void *)0)) { iter->start = 1; return 0; } iter->end = ll_empty(iter->target); iter->cursor = iter->cursor->prev; iter->index--; return 1; } _Bool ll_iter_advance(struct linkedlist_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor->next == ((void *)0)) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; iter->start = ll_empty(iter->target); iter->index += steps; for (size_t i = 0; i < steps; i++) iter->cursor = iter->cursor->next; return 1; } _Bool ll_iter_rewind(struct linkedlist_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor->prev == ((void *)0)) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; iter->end = ll_empty(iter->target); iter->index -= steps; for (size_t i = 0; i < steps; i++) iter->cursor = iter->cursor->prev; return 1; } _Bool ll_iter_go_to(struct linkedlist_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return ll_iter_rewind(iter, iter->index - index); else if (iter->index < index) return ll_iter_advance(iter, index - iter->index); return 1; } size_t ll_iter_value(struct linkedlist_iter * iter) { if (ll_empty(iter->target)) return (size_t){ 0 }; return iter->cursor->value; } size_t *ll_iter_rvalue(struct linkedlist_iter * iter) { if (ll_empty(iter->target)) return ((void *)0); return &(iter->cursor->value); } size_t ll_iter_index(struct linkedlist_iter * iter) { return iter->index; } struct linkedlist_node * ll_iter_node(struct linkedlist_iter * iter) { return iter->cursor; } struct linkedlist_node * ll_new_node(struct linkedlist * _list_, size_t value) { struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node)); if (!_node_) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } _node_->value = value; _node_->next = ((void *)0); _node_->prev = ((void *)0); return _node_; } void ll_free_node(struct linkedlist * _list_, struct linkedlist_node * _node_) { _list_->alloc->free(_node_); } struct linkedlist_node * ll_head(struct linkedlist * _list_) { return _list_->head; } struct linkedlist_node * ll_get_node(struct linkedlist * _list_, size_t index) { if (ll_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } struct linkedlist_node *_node_ = ((void *)0); 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 linkedlist_node * ll_tail(struct linkedlist * _list_) { return _list_->tail; } _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) return 0; new_node->next = _node_->next; if (_node_->next != ((void *)0)) _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 1; } _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) return 0; new_node->prev = _node_->prev; if (_node_->prev != ((void *)0)) _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 1; } _Bool ll_del_next(struct linkedlist * _owner_, struct linkedlist_node * _node_) { if (_node_->next == ((void *)0)) { _owner_->flag = CMC_FLAG_INVALID; return 0; } struct linkedlist_node *tmp = _node_->next; _node_->next = _node_->next->next; if (tmp->next != ((void *)0)) tmp->next->prev = _node_; else _owner_->tail = _node_; _owner_->alloc->free(tmp); _owner_->count--; _owner_->flag = CMC_FLAG_OK; return 1; } _Bool ll_del_curr(struct linkedlist * _owner_, struct linkedlist_node * _node_) { if (_node_->prev != ((void *)0)) _node_->prev->next = _node_->next; else _owner_->head = _node_->next; if (_node_->next != ((void *)0)) _node_->next->prev = _node_->prev; else _owner_->tail = _node_->prev; _owner_->alloc->free(_node_); _owner_->count--; _owner_->flag = CMC_FLAG_OK; return 1; } _Bool ll_del_prev(struct linkedlist * _owner_, struct linkedlist_node * _node_) { if (_node_->prev == ((void *)0)) { _owner_->flag = CMC_FLAG_INVALID; return 0; } struct linkedlist_node *tmp = _node_->prev; _node_->prev = _node_->prev->prev; if (tmp->prev != ((void *)0)) tmp->prev->next = _node_; else _owner_->head = _node_; _owner_->alloc->free(tmp); _owner_->count--; _owner_->flag = CMC_FLAG_OK; return 1; } struct linkedlist_node * ll_next_node(struct linkedlist_node * _node_) { return _node_->next; } struct linkedlist_node * ll_prev_node(struct linkedlist_node * _node_) { return _node_->prev; } _Bool ll_to_string(struct linkedlist * _list_, FILE * fptr) { struct linkedlist *l_ = _list_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "count:%" "I64u" ", " "head:%p, " "tail:%p, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); } _Bool ll_print(struct linkedlist * _list_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); struct linkedlist_node *scan = _list_->head; while (scan != ((void *)0)) { if (!_list_->f_val->str(fptr, scan->value)) return 0; scan = scan->next; if (scan) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +struct linkedlist *ll_new(struct linkedlist_fval *f_val) +{ + return ll_new_custom(f_val, ((void *)0), ((void *)0)); +} +struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (!f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist)); + if (!_list_) + return ((void *)0); + _list_->count = 0; + _list_->head = ((void *)0); + _list_->tail = ((void *)0); + _list_->flag = CMC_FLAG_OK; + _list_->f_val = f_val; + _list_->alloc = alloc; + (_list_)->callbacks = callbacks; + return _list_; +} +void ll_clear(struct linkedlist *_list_) +{ + struct linkedlist_node *scan = _list_->head; + while (_list_->head != ((void *)0)) + { + _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 = ((void *)0); + _list_->tail = ((void *)0); + _list_->flag = CMC_FLAG_OK; +} +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) +{ + ; + if (!alloc) + _list_->alloc = &cmc_alloc_node_default; + else + _list_->alloc = alloc; + (_list_)->callbacks = callbacks; + _list_->flag = CMC_FLAG_OK; +} +_Bool ll_push_front(struct linkedlist *_list_, size_t value) +{ + struct linkedlist_node *_node_ = ll_new_node(_list_, value); + if (!_node_) + return 0; + if (ll_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 1; +} +_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) +{ + if (index > _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + if (index == 0) + { + return ll_push_front(_list_, value); + } + else if (index == _list_->count) + { + return ll_push_back(_list_, value); + } + struct linkedlist_node *_node_ = ll_new_node(_list_, value); + if (!_node_) + return 0; + struct linkedlist_node *scan = ll_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 1; +} +_Bool ll_push_back(struct linkedlist *_list_, size_t value) +{ + struct linkedlist_node *_node_ = ll_new_node(_list_, value); + if (!_node_) + return 0; + if (ll_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 1; +} +_Bool ll_pop_front(struct linkedlist *_list_) +{ + if (ll_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct linkedlist_node *_node_ = _list_->head; + _list_->head = _list_->head->next; + _list_->alloc->free(_node_); + if (_list_->head == ((void *)0)) + _list_->tail = ((void *)0); + else + _list_->head->prev = ((void *)0); + _list_->count--; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +_Bool ll_pop_at(struct linkedlist *_list_, size_t index) +{ + if (ll_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return 0; + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + if (index == 0) + { + return ll_pop_front(_list_); + } + else if (index == _list_->count - 1) + { + return ll_pop_back(_list_); + } + struct linkedlist_node *_node_ = ll_get_node(_list_, index); + if (!_node_) + return 0; + _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 1; +} +_Bool ll_pop_back(struct linkedlist *_list_) +{ + if (ll_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct linkedlist_node *_node_ = _list_->tail; + _list_->tail = _list_->tail->prev; + _list_->alloc->free(_node_); + if (_list_->tail == ((void *)0)) + _list_->head = ((void *)0); + else + _list_->tail->next = ((void *)0); + _list_->count--; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +size_t ll_front(struct linkedlist *_list_) +{ + if (ll_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return _list_->head->value; +} +size_t ll_get(struct linkedlist *_list_, size_t index) +{ + if (ll_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return (size_t){ 0 }; + } + struct linkedlist_node *scan = ll_get_node(_list_, index); + if (scan == ((void *)0)) + return (size_t){ 0 }; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return scan->value; +} +size_t *ll_get_ref(struct linkedlist *_list_, size_t index) +{ + if (ll_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return ((void *)0); + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return ((void *)0); + } + struct linkedlist_node *scan = ll_get_node(_list_, index); + if (scan == ((void *)0)) + return ((void *)0); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return &(scan->value); +} +size_t ll_back(struct linkedlist *_list_) +{ + if (ll_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return _list_->tail->value; +} +_Bool ll_contains(struct linkedlist *_list_, size_t value) +{ + _list_->flag = CMC_FLAG_OK; + _Bool result = 0; + struct linkedlist_node *scan = _list_->head; + while (scan != ((void *)0)) + { + if (_list_->f_val->cmp(scan->value, value) == 0) + { + result = 1; + break; + } + scan = scan->next; + } + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return result; +} +_Bool ll_empty(struct linkedlist *_list_) +{ + return _list_->count == 0; +} +size_t ll_count(struct linkedlist *_list_) +{ + return _list_->count; +} +int ll_flag(struct linkedlist *_list_) +{ + return _list_->flag; +} +struct linkedlist *ll_copy_of(struct linkedlist *_list_) +{ + struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0)); + if (!result) + return ((void *)0); + (result)->callbacks = _list_->callbacks; + struct linkedlist_node *scan = _list_->head; + while (scan != ((void *)0)) + { + struct linkedlist_node *new_node; + if (_list_->f_val->cpy) + new_node = ll_new_node(_list_, _list_->f_val->cpy(scan->value)); + else + new_node = ll_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 ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) +{ + _list1_->flag = CMC_FLAG_OK; + _list2_->flag = CMC_FLAG_OK; + if (_list1_->count != _list2_->count) + return 0; + struct linkedlist_node *scan1 = _list1_->head; + struct linkedlist_node *scan2 = _list2_->head; + while (scan1 != ((void *)0) && scan2 != ((void *)0)) + { + if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) + return 0; + scan1 = scan1->next; + scan2 = scan2->next; + } + return 1; +} +struct linkedlist_iter ll_iter_start(struct linkedlist *target) +{ + struct linkedlist_iter iter; + iter.target = target; + iter.cursor = target->head; + iter.index = 0; + iter.start = 1; + iter.end = ll_empty(target); + return iter; +} +struct linkedlist_iter ll_iter_end(struct linkedlist *target) +{ + struct linkedlist_iter iter; + iter.target = target; + iter.cursor = target->tail; + iter.index = 0; + iter.start = ll_empty(target); + iter.end = 1; + if (!ll_empty(target)) + iter.index = target->count - 1; + return iter; +} +_Bool ll_iter_at_start(struct linkedlist_iter *iter) +{ + return ll_empty(iter->target) || iter->start; +} +_Bool ll_iter_at_end(struct linkedlist_iter *iter) +{ + return ll_empty(iter->target) || iter->end; +} +_Bool ll_iter_to_start(struct linkedlist_iter *iter) +{ + if (!ll_empty(iter->target)) + { + iter->cursor = iter->target->head; + iter->index = 0; + iter->start = 1; + iter->end = ll_empty(iter->target); + return 1; + } + return 0; +} +_Bool ll_iter_to_end(struct linkedlist_iter *iter) +{ + if (!ll_empty(iter->target)) + { + iter->cursor = iter->target->tail; + iter->index = iter->target->count - 1; + iter->start = ll_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool ll_iter_next(struct linkedlist_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor->next == ((void *)0)) + { + iter->end = 1; + return 0; + } + iter->start = ll_empty(iter->target); + iter->cursor = iter->cursor->next; + iter->index++; + return 1; +} +_Bool ll_iter_prev(struct linkedlist_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor->prev == ((void *)0)) + { + iter->start = 1; + return 0; + } + iter->end = ll_empty(iter->target); + iter->cursor = iter->cursor->prev; + iter->index--; + return 1; +} +_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor->next == ((void *)0)) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + iter->start = ll_empty(iter->target); + iter->index += steps; + for (size_t i = 0; i < steps; i++) + iter->cursor = iter->cursor->next; + return 1; +} +_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor->prev == ((void *)0)) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + iter->end = ll_empty(iter->target); + iter->index -= steps; + for (size_t i = 0; i < steps; i++) + iter->cursor = iter->cursor->prev; + return 1; +} +_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return ll_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return ll_iter_advance(iter, index - iter->index); + return 1; +} +size_t ll_iter_value(struct linkedlist_iter *iter) +{ + if (ll_empty(iter->target)) + return (size_t){ 0 }; + return iter->cursor->value; +} +size_t *ll_iter_rvalue(struct linkedlist_iter *iter) +{ + if (ll_empty(iter->target)) + return ((void *)0); + return &(iter->cursor->value); +} +size_t ll_iter_index(struct linkedlist_iter *iter) +{ + return iter->index; +} +struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter) +{ + return iter->cursor; +} +struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) +{ + struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node)); + if (!_node_) + { + _list_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + _node_->value = value; + _node_->next = ((void *)0); + _node_->prev = ((void *)0); + return _node_; +} +void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_) +{ + _list_->alloc->free(_node_); +} +struct linkedlist_node *ll_head(struct linkedlist *_list_) +{ + return _list_->head; +} +struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index) +{ + if (ll_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return ((void *)0); + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return ((void *)0); + } + struct linkedlist_node *_node_ = ((void *)0); + 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 linkedlist_node *ll_tail(struct linkedlist *_list_) +{ + return _list_->tail; +} +_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) + return 0; + new_node->next = _node_->next; + if (_node_->next != ((void *)0)) + _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 1; +} +_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) + return 0; + new_node->prev = _node_->prev; + if (_node_->prev != ((void *)0)) + _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 1; +} +_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_) +{ + if (_node_->next == ((void *)0)) + { + _owner_->flag = CMC_FLAG_INVALID; + return 0; + } + struct linkedlist_node *tmp = _node_->next; + _node_->next = _node_->next->next; + if (tmp->next != ((void *)0)) + tmp->next->prev = _node_; + else + _owner_->tail = _node_; + _owner_->alloc->free(tmp); + _owner_->count--; + _owner_->flag = CMC_FLAG_OK; + return 1; +} +_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_) +{ + if (_node_->prev != ((void *)0)) + _node_->prev->next = _node_->next; + else + _owner_->head = _node_->next; + if (_node_->next != ((void *)0)) + _node_->next->prev = _node_->prev; + else + _owner_->tail = _node_->prev; + _owner_->alloc->free(_node_); + _owner_->count--; + _owner_->flag = CMC_FLAG_OK; + return 1; +} +_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_) +{ + if (_node_->prev == ((void *)0)) + { + _owner_->flag = CMC_FLAG_INVALID; + return 0; + } + struct linkedlist_node *tmp = _node_->prev; + _node_->prev = _node_->prev->prev; + if (tmp->prev != ((void *)0)) + tmp->prev->next = _node_; + else + _owner_->head = _node_; + _owner_->alloc->free(tmp); + _owner_->count--; + _owner_->flag = CMC_FLAG_OK; + return 1; +} +struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_) +{ + return _node_->next; +} +struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_) +{ + return _node_->prev; +} +_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr) +{ + struct linkedlist *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "count:%" + "I64u" + ", " + "head:%p, " + "tail:%p, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, + (l_)->callbacks); +} +_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + struct linkedlist_node *scan = _list_->head; + while (scan != ((void *)0)) + { + if (!_list_->f_val->str(fptr, scan->value)) + return 0; + scan = scan->next; + if (scan) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_list.c b/tests/src/tst_cmc_list.c index a0061d8..6ada698 100644 --- a/tests/src/tst_cmc_list.c +++ b/tests/src/tst_cmc_list.c @@ -1,7 +1,643 @@ - #include "tst_cmc_list.h" +#include "tst_cmc_list.h" - - struct list *l_new(size_t capacity, struct list_fval * f_val) { return l_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct list *l_new_custom(size_t capacity, struct list_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct list *_list_ = alloc->malloc(sizeof(struct list)); if (!_list_) return ((void *)0); _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_list_->buffer) { alloc->free(_list_); return ((void *)0); } _list_->capacity = capacity; _list_->count = 0; _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; (_list_)->callbacks = callbacks; return _list_; } void l_clear(struct list * _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(size_t) * _list_->capacity); _list_->count = 0; _list_->flag = CMC_FLAG_OK; } void l_free(struct list * _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 l_customize(struct list * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool l_push_front(struct list * _list_, size_t value) { if (l_full(_list_)) { if (!l_resize(_list_, _list_->count * 2)) return 0; } if (!l_empty(_list_)) { memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(size_t)); } _list_->buffer[0] = value; _list_->count++; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_push_at(struct list * _list_, size_t value, size_t index) { if (index > _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } if (l_full(_list_)) { if (!l_resize(_list_, _list_->count * 2)) return 0; } 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; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_push_back(struct list * _list_, size_t value) { if (l_full(_list_)) { if (!l_resize(_list_, _list_->count * 2)) return 0; } _list_->buffer[_list_->count++] = value; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_pop_front(struct list * _list_) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } _Bool l_pop_at(struct list * _list_, size_t index) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } _Bool l_pop_back(struct list * _list_) { if (l_empty(_list_)) return 0; _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } size_t l_front(struct list * _list_) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[0]; } size_t l_get(struct list * _list_, size_t index) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[index]; } size_t *l_get_ref(struct list * _list_, size_t index) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return ((void *)0); } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return &(_list_->buffer[index]); } size_t l_back(struct list * _list_) { if (l_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[_list_->count - 1]; } size_t l_index_of(struct list * _list_, size_t value, _Bool from_start) { _list_->flag = CMC_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 l_contains(struct list * _list_, size_t value) { _list_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _list_->count; i++) { if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) { result = 1; break; } } if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return result; } _Bool l_empty(struct list * _list_) { return _list_->count == 0; } _Bool l_full(struct list * _list_) { return _list_->count >= _list_->capacity; } size_t l_count(struct list * _list_) { return _list_->count; } _Bool l_fits(struct list * _list_, size_t size) { return _list_->count + size <= _list_->capacity; } size_t l_capacity(struct list * _list_) { return _list_->capacity; } int l_flag(struct list * _list_) { return _list_->flag; } _Bool l_resize(struct list * _list_, size_t capacity) { _list_->flag = CMC_FLAG_OK; if (_list_->capacity == capacity) return 1; if (capacity < _list_->count) { _list_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _list_->flag = CMC_FLAG_ALLOC; return 0; } _list_->buffer = new_buffer; _list_->capacity = capacity; if ((_list_)->callbacks && (_list_)->callbacks->resize) (_list_)->callbacks->resize();; return 1; } struct list *l_copy_of(struct list * _list_) { struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); if (!result) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } (result)->callbacks = _list_->callbacks; if (_list_->f_val->cpy) { for (size_t i = 0; i < _list_->count; i++) result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); } else memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); result->count = _list_->count; _list_->flag = CMC_FLAG_OK; return result; } _Bool l_equals(struct list * _list1_, struct list * _list2_) { _list1_->flag = CMC_FLAG_OK; _list2_->flag = CMC_FLAG_OK; if (_list1_->count != _list2_->count) return 0; for (size_t i = 0; i < _list1_->count; i++) { if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) return 0; } return 1; } struct list_iter l_iter_start(struct list * target) { struct list_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = l_empty(target); return iter; } struct list_iter l_iter_end(struct list * target) { struct list_iter iter; iter.target = target; iter.cursor = 0; iter.start = l_empty(target); iter.end = 1; if (!l_empty(target)) iter.cursor = target->count - 1; return iter; } _Bool l_iter_at_start(struct list_iter * iter) { return l_empty(iter->target) || iter->start; } _Bool l_iter_at_end(struct list_iter * iter) { return l_empty(iter->target) || iter->end; } _Bool l_iter_to_start(struct list_iter * iter) { if (!l_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = l_empty(iter->target); return 1; } return 0; } _Bool l_iter_to_end(struct list_iter * iter) { if (!l_empty(iter->target)) { iter->start = l_empty(iter->target); iter->cursor = iter->target->count - 1; iter->end = 1; return 1; } return 0; } _Bool l_iter_next(struct list_iter * iter) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = l_empty(iter->target); iter->cursor++; return 1; } _Bool l_iter_prev(struct list_iter * iter) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } iter->end = l_empty(iter->target); iter->cursor--; return 1; } _Bool l_iter_advance(struct list_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; iter->start = l_empty(iter->target); iter->cursor += steps; return 1; } _Bool l_iter_rewind(struct list_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->end = l_empty(iter->target); iter->cursor -= steps; return 1; } _Bool l_iter_go_to(struct list_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return l_iter_rewind(iter, iter->cursor - index); else if (iter->cursor < index) return l_iter_advance(iter, index - iter->cursor); return 1; } size_t l_iter_value(struct list_iter * iter) { if (l_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t *l_iter_rvalue(struct list_iter * iter) { if (l_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor]); } size_t l_iter_index(struct list_iter * iter) { return iter->cursor; } _Bool l_seq_push_front(struct list * _list_, size_t * values, size_t size) { if (size == 0) { _list_->flag = CMC_FLAG_INVALID; return 0; } if (!l_fits(_list_, size)) { if (!l_resize(_list_, _list_->count + size)) return 0; } memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); memcpy(_list_->buffer, values, size * sizeof(size_t)); _list_->count += size; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_seq_push_at(struct list * _list_, size_t * values, size_t size, size_t index) { if (size == 0) { _list_->flag = CMC_FLAG_INVALID; return 0; } if (index > _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } if (index == 0) return l_seq_push_front(_list_, values, size); else if (index == _list_->count) return l_seq_push_back(_list_, values, size); if (!l_fits(_list_, size)) { if (!l_resize(_list_, _list_->count + size)) return 0; } memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); memcpy(_list_->buffer + index, values, size * sizeof(size_t)); _list_->count += size; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_seq_push_back(struct list * _list_, size_t * values, size_t size) { if (size == 0) { _list_->flag = CMC_FLAG_INVALID; return 0; } if (!l_fits(_list_, size)) { if (!l_resize(_list_, _list_->count + size)) return 0; } memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); _list_->count += size; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool l_seq_pop_at(struct list * _list_, size_t from, size_t to) { if (from > to) { _list_->flag = CMC_FLAG_INVALID; return 0; } if (to >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } size_t length = (to - from + 1); memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); _list_->count -= to - from + 1; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } struct list *l_seq_sublist(struct list * _list_, size_t from, size_t to) { if (from > to) { _list_->flag = CMC_FLAG_INVALID; return ((void *)0); } if (to >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return ((void *)0); } size_t length = to - from + 1; struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks); if (!result) { _list_->flag = CMC_FLAG_ALLOC; return ((void *)0); } memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); _list_->count -= length; result->count = length; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return result; } _Bool l_to_string(struct list * _list_, FILE * fptr) { struct list *l_ = _list_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); } _Bool l_print(struct list * _list_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = 0; i < _list_->count; i++) { if (!_list_->f_val->str(fptr, _list_->buffer[i])) return 0; if (i + 1 < _list_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +struct list *l_new(size_t capacity, struct list_fval *f_val) +{ + return l_new_custom(capacity, f_val, ((void *)0), ((void *)0)); +} +struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (capacity < 1) + return ((void *)0); + if (!f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct list *_list_ = alloc->malloc(sizeof(struct list)); + if (!_list_) + return ((void *)0); + _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_list_->buffer) + { + alloc->free(_list_); + return ((void *)0); + } + _list_->capacity = capacity; + _list_->count = 0; + _list_->flag = CMC_FLAG_OK; + _list_->f_val = f_val; + _list_->alloc = alloc; + (_list_)->callbacks = callbacks; + return _list_; +} +void l_clear(struct list *_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(size_t) * _list_->capacity); + _list_->count = 0; + _list_->flag = CMC_FLAG_OK; +} +void l_free(struct list *_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 l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _list_->alloc = &cmc_alloc_node_default; + else + _list_->alloc = alloc; + (_list_)->callbacks = callbacks; + _list_->flag = CMC_FLAG_OK; +} +_Bool l_push_front(struct list *_list_, size_t value) +{ + if (l_full(_list_)) + { + if (!l_resize(_list_, _list_->count * 2)) + return 0; + } + if (!l_empty(_list_)) + { + memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(size_t)); + } + _list_->buffer[0] = value; + _list_->count++; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_push_at(struct list *_list_, size_t value, size_t index) +{ + if (index > _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + if (l_full(_list_)) + { + if (!l_resize(_list_, _list_->count * 2)) + return 0; + } + 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; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_push_back(struct list *_list_, size_t value) +{ + if (l_full(_list_)) + { + if (!l_resize(_list_, _list_->count * 2)) + return 0; + } + _list_->buffer[_list_->count++] = value; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_pop_front(struct list *_list_) +{ + if (l_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return 0; + } + memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); + _list_->buffer[--_list_->count] = (size_t){ 0 }; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +_Bool l_pop_at(struct list *_list_, size_t index) +{ + if (l_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return 0; + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); + _list_->buffer[--_list_->count] = (size_t){ 0 }; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +_Bool l_pop_back(struct list *_list_) +{ + if (l_empty(_list_)) + return 0; + _list_->buffer[--_list_->count] = (size_t){ 0 }; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +size_t l_front(struct list *_list_) +{ + if (l_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return _list_->buffer[0]; +} +size_t l_get(struct list *_list_, size_t index) +{ + if (l_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return (size_t){ 0 }; + } + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return _list_->buffer[index]; +} +size_t *l_get_ref(struct list *_list_, size_t index) +{ + if (l_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return ((void *)0); + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return ((void *)0); + } + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return &(_list_->buffer[index]); +} +size_t l_back(struct list *_list_) +{ + if (l_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return _list_->buffer[_list_->count - 1]; +} +size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) +{ + _list_->flag = CMC_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 l_contains(struct list *_list_, size_t value) +{ + _list_->flag = CMC_FLAG_OK; + _Bool result = 0; + for (size_t i = 0; i < _list_->count; i++) + { + if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) + { + result = 1; + break; + } + } + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return result; +} +_Bool l_empty(struct list *_list_) +{ + return _list_->count == 0; +} +_Bool l_full(struct list *_list_) +{ + return _list_->count >= _list_->capacity; +} +size_t l_count(struct list *_list_) +{ + return _list_->count; +} +_Bool l_fits(struct list *_list_, size_t size) +{ + return _list_->count + size <= _list_->capacity; +} +size_t l_capacity(struct list *_list_) +{ + return _list_->capacity; +} +int l_flag(struct list *_list_) +{ + return _list_->flag; +} +_Bool l_resize(struct list *_list_, size_t capacity) +{ + _list_->flag = CMC_FLAG_OK; + if (_list_->capacity == capacity) + return 1; + if (capacity < _list_->count) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); + if (!new_buffer) + { + _list_->flag = CMC_FLAG_ALLOC; + return 0; + } + _list_->buffer = new_buffer; + _list_->capacity = capacity; + if ((_list_)->callbacks && (_list_)->callbacks->resize) + (_list_)->callbacks->resize(); + ; + return 1; +} +struct list *l_copy_of(struct list *_list_) +{ + struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); + if (!result) + { + _list_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + (result)->callbacks = _list_->callbacks; + if (_list_->f_val->cpy) + { + for (size_t i = 0; i < _list_->count; i++) + result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); + } + else + memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); + result->count = _list_->count; + _list_->flag = CMC_FLAG_OK; + return result; +} +_Bool l_equals(struct list *_list1_, struct list *_list2_) +{ + _list1_->flag = CMC_FLAG_OK; + _list2_->flag = CMC_FLAG_OK; + if (_list1_->count != _list2_->count) + return 0; + for (size_t i = 0; i < _list1_->count; i++) + { + if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) + return 0; + } + return 1; +} +struct list_iter l_iter_start(struct list *target) +{ + struct list_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = l_empty(target); + return iter; +} +struct list_iter l_iter_end(struct list *target) +{ + struct list_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = l_empty(target); + iter.end = 1; + if (!l_empty(target)) + iter.cursor = target->count - 1; + return iter; +} +_Bool l_iter_at_start(struct list_iter *iter) +{ + return l_empty(iter->target) || iter->start; +} +_Bool l_iter_at_end(struct list_iter *iter) +{ + return l_empty(iter->target) || iter->end; +} +_Bool l_iter_to_start(struct list_iter *iter) +{ + if (!l_empty(iter->target)) + { + iter->cursor = 0; + iter->start = 1; + iter->end = l_empty(iter->target); + return 1; + } + return 0; +} +_Bool l_iter_to_end(struct list_iter *iter) +{ + if (!l_empty(iter->target)) + { + iter->start = l_empty(iter->target); + iter->cursor = iter->target->count - 1; + iter->end = 1; + return 1; + } + return 0; +} +_Bool l_iter_next(struct list_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = l_empty(iter->target); + iter->cursor++; + return 1; +} +_Bool l_iter_prev(struct list_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + iter->end = l_empty(iter->target); + iter->cursor--; + return 1; +} +_Bool l_iter_advance(struct list_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return 0; + iter->start = l_empty(iter->target); + iter->cursor += steps; + return 1; +} +_Bool l_iter_rewind(struct list_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->cursor < steps) + return 0; + iter->end = l_empty(iter->target); + iter->cursor -= steps; + return 1; +} +_Bool l_iter_go_to(struct list_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->cursor > index) + return l_iter_rewind(iter, iter->cursor - index); + else if (iter->cursor < index) + return l_iter_advance(iter, index - iter->cursor); + return 1; +} +size_t l_iter_value(struct list_iter *iter) +{ + if (l_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor]; +} +size_t *l_iter_rvalue(struct list_iter *iter) +{ + if (l_empty(iter->target)) + return ((void *)0); + return &(iter->target->buffer[iter->cursor]); +} +size_t l_iter_index(struct list_iter *iter) +{ + return iter->cursor; +} +_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); + memcpy(_list_->buffer, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (index > _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + if (index == 0) + return l_seq_push_front(_list_, values, size); + else if (index == _list_->count) + return l_seq_push_back(_list_, values, size); + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); + memcpy(_list_->buffer + index, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (!l_fits(_list_, size)) + { + if (!l_resize(_list_, _list_->count + size)) + return 0; + } + memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) +{ + if (from > to) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + if (to >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + size_t length = (to - from + 1); + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); + _list_->count -= to - from + 1; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) +{ + if (from > to) + { + _list_->flag = CMC_FLAG_INVALID; + return ((void *)0); + } + if (to >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return ((void *)0); + } + size_t length = to - from + 1; + struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks); + if (!result) + { + _list_->flag = CMC_FLAG_ALLOC; + return ((void *)0); + } + memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); + _list_->count -= length; + result->count = length; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return result; +} +_Bool l_to_string(struct list *_list_, FILE *fptr) +{ + struct list *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, + (l_)->callbacks); +} +_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _list_->count; i++) + { + if (!_list_->f_val->str(fptr, _list_->buffer[i])) + return 0; + if (i + 1 < _list_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_queue.c b/tests/src/tst_cmc_queue.c index 9ae20dc..82dc6cb 100644 --- a/tests/src/tst_cmc_queue.c +++ b/tests/src/tst_cmc_queue.c @@ -1,7 +1,431 @@ - #include "tst_cmc_queue.h" +#include "tst_cmc_queue.h" - - struct queue *q_new(size_t capacity, struct queue_fval * f_val) { return q_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct queue *q_new_custom(size_t capacity, struct queue_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct queue *_queue_ = alloc->malloc(sizeof(struct queue)); if (!_queue_) return ((void *)0); _queue_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_queue_->buffer) { alloc->free(_queue_); return ((void *)0); } _queue_->capacity = capacity; _queue_->count = 0; _queue_->front = 0; _queue_->back = 0; _queue_->flag = CMC_FLAG_OK; _queue_->f_val = f_val; _queue_->alloc = alloc; (_queue_)->callbacks = callbacks; return _queue_; } void q_clear(struct queue * _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(size_t) * _queue_->capacity); _queue_->count = 0; _queue_->front = 0; _queue_->back = 0; _queue_->flag = CMC_FLAG_OK; } void q_free(struct queue * _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 q_customize(struct queue * _queue_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _queue_->alloc = &cmc_alloc_node_default; else _queue_->alloc = alloc; (_queue_)->callbacks = callbacks; _queue_->flag = CMC_FLAG_OK; } _Bool q_enqueue(struct queue * _queue_, size_t value) { if (q_full(_queue_)) { if (!q_resize(_queue_, _queue_->capacity * 2)) return 0; } _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 1; } _Bool q_dequeue(struct queue * _queue_) { if (q_empty(_queue_)) { _queue_->flag = CMC_FLAG_EMPTY; return 0; } _queue_->buffer[_queue_->front] = (size_t){ 0 }; _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; _queue_->count--; _queue_->flag = CMC_FLAG_OK; if ((_queue_)->callbacks && (_queue_)->callbacks->delete) (_queue_)->callbacks->delete();; return 1; } size_t q_peek(struct queue * _queue_) { if (q_empty(_queue_)) { _queue_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _queue_->flag = CMC_FLAG_OK; if ((_queue_)->callbacks && (_queue_)->callbacks->read) (_queue_)->callbacks->read();; return _queue_->buffer[_queue_->front]; } _Bool q_contains(struct queue * _queue_, size_t value) { _queue_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) { if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) { result = 1; break; } i = (i + 1) % _queue_->capacity; } if ((_queue_)->callbacks && (_queue_)->callbacks->read) (_queue_)->callbacks->read();; return result; } _Bool q_empty(struct queue * _queue_) { return _queue_->count == 0; } _Bool q_full(struct queue * _queue_) { return _queue_->count >= _queue_->capacity; } size_t q_count(struct queue * _queue_) { return _queue_->count; } size_t q_capacity(struct queue * _queue_) { return _queue_->capacity; } int q_flag(struct queue * _queue_) { return _queue_->flag; } _Bool q_resize(struct queue * _queue_, size_t capacity) { if (_queue_->capacity == capacity) goto success; if (capacity < _queue_->count) { _queue_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _queue_->alloc->malloc(sizeof(size_t) * capacity); if (!new_buffer) { _queue_->flag = CMC_FLAG_ALLOC; return 0; } 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 1; } struct queue *q_copy_of(struct queue * _queue_) { struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0)); if (!result) { _queue_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _queue_->callbacks; if (_queue_->f_val->cpy) { for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) { 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 q_equals(struct queue * _queue1_, struct queue * _queue2_) { _queue1_->flag = CMC_FLAG_OK; _queue2_->flag = CMC_FLAG_OK; 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++) { if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) return 0; i = (i + 1) % _queue1_->capacity; j = (j + 1) % _queue2_->capacity; } return 1; } struct queue_iter q_iter_start(struct queue * target) { struct queue_iter iter; iter.target = target; iter.cursor = target->front; iter.index = 0; iter.start = 1; iter.end = q_empty(target); return iter; } struct queue_iter q_iter_end(struct queue * target) { struct queue_iter iter; iter.target = target; if (!q_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 = q_empty(target); iter.end = 1; return iter; } _Bool q_iter_at_start(struct queue_iter * iter) { return q_empty(iter->target) || iter->start; } _Bool q_iter_at_end(struct queue_iter * iter) { return q_empty(iter->target) || iter->end; } _Bool q_iter_to_start(struct queue_iter * iter) { if (!q_empty(iter->target)) { iter->cursor = iter->target->front; iter->index = 0; iter->start = 1; iter->end = 0; return 1; } return 0; } _Bool q_iter_to_end(struct queue_iter * iter) { if (!q_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 = 0; iter->end = 1; return 1; } return 0; } _Bool q_iter_next(struct queue_iter * iter) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = q_empty(iter->target); iter->cursor = (iter->cursor + 1) % (iter->target->capacity); iter->index++; return 1; } _Bool q_iter_prev(struct queue_iter * iter) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } iter->end = q_empty(iter->target); iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; iter->index--; return 1; } _Bool q_iter_advance(struct queue_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->index + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; iter->start = q_empty(iter->target); iter->index += steps; iter->cursor = (iter->cursor + steps) % iter->target->capacity; return 1; } _Bool q_iter_rewind(struct queue_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->index == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; iter->end = q_empty(iter->target); iter->index -= steps; if (iter->cursor < steps) iter->cursor += iter->target->capacity; iter->cursor -= steps; return 1; } _Bool q_iter_go_to(struct queue_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return q_iter_rewind(iter, iter->index - index); else if (iter->index < index) return q_iter_advance(iter, index - iter->index); return 1; } size_t q_iter_value(struct queue_iter * iter) { if (q_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t *q_iter_rvalue(struct queue_iter * iter) { if (q_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor]); } size_t q_iter_index(struct queue_iter * iter) { return iter->index; } _Bool q_to_string(struct queue * _queue_, FILE * fptr) { struct queue *q_ = _queue_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "front:%" "I64u" ", " "back:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag, q_->f_val, q_->alloc, (q_)->callbacks); } _Bool q_print(struct queue * _queue_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) { if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) return 0; i = (i + 1) % _queue_->capacity; if (j + 1 < _queue_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +struct queue *q_new(size_t capacity, struct queue_fval *f_val) +{ + return q_new_custom(capacity, f_val, ((void *)0), ((void *)0)); +} +struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (capacity < 1) + return ((void *)0); + if (!f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct queue *_queue_ = alloc->malloc(sizeof(struct queue)); + if (!_queue_) + return ((void *)0); + _queue_->buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_queue_->buffer) + { + alloc->free(_queue_); + return ((void *)0); + } + _queue_->capacity = capacity; + _queue_->count = 0; + _queue_->front = 0; + _queue_->back = 0; + _queue_->flag = CMC_FLAG_OK; + _queue_->f_val = f_val; + _queue_->alloc = alloc; + (_queue_)->callbacks = callbacks; + return _queue_; +} +void q_clear(struct queue *_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(size_t) * _queue_->capacity); + _queue_->count = 0; + _queue_->front = 0; + _queue_->back = 0; + _queue_->flag = CMC_FLAG_OK; +} +void q_free(struct queue *_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 q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _queue_->alloc = &cmc_alloc_node_default; + else + _queue_->alloc = alloc; + (_queue_)->callbacks = callbacks; + _queue_->flag = CMC_FLAG_OK; +} +_Bool q_enqueue(struct queue *_queue_, size_t value) +{ + if (q_full(_queue_)) + { + if (!q_resize(_queue_, _queue_->capacity * 2)) + return 0; + } + _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 1; +} +_Bool q_dequeue(struct queue *_queue_) +{ + if (q_empty(_queue_)) + { + _queue_->flag = CMC_FLAG_EMPTY; + return 0; + } + _queue_->buffer[_queue_->front] = (size_t){ 0 }; + _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; + _queue_->count--; + _queue_->flag = CMC_FLAG_OK; + if ((_queue_)->callbacks && (_queue_)->callbacks->delete) + (_queue_)->callbacks->delete (); + ; + return 1; +} +size_t q_peek(struct queue *_queue_) +{ + if (q_empty(_queue_)) + { + _queue_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _queue_->flag = CMC_FLAG_OK; + if ((_queue_)->callbacks && (_queue_)->callbacks->read) + (_queue_)->callbacks->read(); + ; + return _queue_->buffer[_queue_->front]; +} +_Bool q_contains(struct queue *_queue_, size_t value) +{ + _queue_->flag = CMC_FLAG_OK; + _Bool result = 0; + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) + { + if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) + { + result = 1; + break; + } + i = (i + 1) % _queue_->capacity; + } + if ((_queue_)->callbacks && (_queue_)->callbacks->read) + (_queue_)->callbacks->read(); + ; + return result; +} +_Bool q_empty(struct queue *_queue_) +{ + return _queue_->count == 0; +} +_Bool q_full(struct queue *_queue_) +{ + return _queue_->count >= _queue_->capacity; +} +size_t q_count(struct queue *_queue_) +{ + return _queue_->count; +} +size_t q_capacity(struct queue *_queue_) +{ + return _queue_->capacity; +} +int q_flag(struct queue *_queue_) +{ + return _queue_->flag; +} +_Bool q_resize(struct queue *_queue_, size_t capacity) +{ + if (_queue_->capacity == capacity) + goto success; + if (capacity < _queue_->count) + { + _queue_->flag = CMC_FLAG_INVALID; + return 0; + } + size_t *new_buffer = _queue_->alloc->malloc(sizeof(size_t) * capacity); + if (!new_buffer) + { + _queue_->flag = CMC_FLAG_ALLOC; + return 0; + } + 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 1; +} +struct queue *q_copy_of(struct queue *_queue_) +{ + struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0)); + if (!result) + { + _queue_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _queue_->callbacks; + if (_queue_->f_val->cpy) + { + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) + { + 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 q_equals(struct queue *_queue1_, struct queue *_queue2_) +{ + _queue1_->flag = CMC_FLAG_OK; + _queue2_->flag = CMC_FLAG_OK; + 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++) + { + if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) + return 0; + i = (i + 1) % _queue1_->capacity; + j = (j + 1) % _queue2_->capacity; + } + return 1; +} +struct queue_iter q_iter_start(struct queue *target) +{ + struct queue_iter iter; + iter.target = target; + iter.cursor = target->front; + iter.index = 0; + iter.start = 1; + iter.end = q_empty(target); + return iter; +} +struct queue_iter q_iter_end(struct queue *target) +{ + struct queue_iter iter; + iter.target = target; + if (!q_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 = q_empty(target); + iter.end = 1; + return iter; +} +_Bool q_iter_at_start(struct queue_iter *iter) +{ + return q_empty(iter->target) || iter->start; +} +_Bool q_iter_at_end(struct queue_iter *iter) +{ + return q_empty(iter->target) || iter->end; +} +_Bool q_iter_to_start(struct queue_iter *iter) +{ + if (!q_empty(iter->target)) + { + iter->cursor = iter->target->front; + iter->index = 0; + iter->start = 1; + iter->end = 0; + return 1; + } + return 0; +} +_Bool q_iter_to_end(struct queue_iter *iter) +{ + if (!q_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 = 0; + iter->end = 1; + return 1; + } + return 0; +} +_Bool q_iter_next(struct queue_iter *iter) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = q_empty(iter->target); + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); + iter->index++; + return 1; +} +_Bool q_iter_prev(struct queue_iter *iter) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + iter->end = q_empty(iter->target); + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; + iter->index--; + return 1; +} +_Bool q_iter_advance(struct queue_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->index + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + iter->start = q_empty(iter->target); + iter->index += steps; + iter->cursor = (iter->cursor + steps) % iter->target->capacity; + return 1; +} +_Bool q_iter_rewind(struct queue_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->index == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + iter->end = q_empty(iter->target); + iter->index -= steps; + if (iter->cursor < steps) + iter->cursor += iter->target->capacity; + iter->cursor -= steps; + return 1; +} +_Bool q_iter_go_to(struct queue_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return q_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return q_iter_advance(iter, index - iter->index); + return 1; +} +size_t q_iter_value(struct queue_iter *iter) +{ + if (q_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor]; +} +size_t *q_iter_rvalue(struct queue_iter *iter) +{ + if (q_empty(iter->target)) + return ((void *)0); + return &(iter->target->buffer[iter->cursor]); +} +size_t q_iter_index(struct queue_iter *iter) +{ + return iter->index; +} +_Bool q_to_string(struct queue *_queue_, FILE *fptr) +{ + struct queue *q_ = _queue_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "front:%" + "I64u" + ", " + "back:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag, + q_->f_val, q_->alloc, (q_)->callbacks); +} +_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) + { + if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) + return 0; + i = (i + 1) % _queue_->capacity; + if (j + 1 < _queue_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_sortedlist.c b/tests/src/tst_cmc_sortedlist.c index 75c57f9..ae46830 100644 --- a/tests/src/tst_cmc_sortedlist.c +++ b/tests/src/tst_cmc_sortedlist.c @@ -1,7 +1,512 @@ - #include "tst_cmc_sortedlist.h" +#include "tst_cmc_sortedlist.h" - - 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) { return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist)); if (!_list_) return ((void *)0); _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_list_->buffer) { alloc->free(_list_); return ((void *)0); } _list_->capacity = capacity; _list_->count = 0; _list_->is_sorted = 0; _list_->flag = CMC_FLAG_OK; _list_->f_val = f_val; _list_->alloc = alloc; (_list_)->callbacks = callbacks; return _list_; } void sl_clear(struct sortedlist * _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(size_t) * _list_->capacity); _list_->count = 0; _list_->flag = CMC_FLAG_OK; } void sl_free(struct sortedlist * _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 sl_customize(struct sortedlist * _list_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _list_->alloc = &cmc_alloc_node_default; else _list_->alloc = alloc; (_list_)->callbacks = callbacks; _list_->flag = CMC_FLAG_OK; } _Bool sl_insert(struct sortedlist * _list_, size_t value) { if (sl_full(_list_)) { if (!sl_resize(_list_, _list_->capacity * 2)) return 0; } _list_->buffer[_list_->count++] = value; _list_->is_sorted = 0; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->create) (_list_)->callbacks->create();; return 1; } _Bool sl_remove(struct sortedlist * _list_, size_t index) { if (sl_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return 0; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return 0; } memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); _list_->buffer[--_list_->count] = (size_t){ 0 }; _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->delete) (_list_)->callbacks->delete();; return 1; } size_t sl_max(struct sortedlist * _list_) { if (sl_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[_list_->count - 1]; } size_t sl_min(struct sortedlist * _list_) { if (sl_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[0]; } size_t sl_get(struct sortedlist * _list_, size_t index) { if (sl_empty(_list_)) { _list_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } if (index >= _list_->count) { _list_->flag = CMC_FLAG_RANGE; return (size_t){ 0 }; } sl_sort(_list_); _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return _list_->buffer[index]; } size_t sl_index_of(struct sortedlist * _list_, size_t value, _Bool from_start) { _list_->flag = CMC_FLAG_OK; sl_sort(_list_); if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; if (from_start) { return sl_impl_binary_search_first(_list_, value); } return sl_impl_binary_search_last(_list_, value); } _Bool sl_contains(struct sortedlist * _list_, size_t value) { _list_->flag = CMC_FLAG_OK; if (sl_empty(_list_)) return 0; sl_sort(_list_); if ((_list_)->callbacks && (_list_)->callbacks->read) (_list_)->callbacks->read();; return sl_impl_binary_search_first(_list_, value) < _list_->count; } _Bool sl_empty(struct sortedlist * _list_) { return _list_->count == 0; } _Bool sl_full(struct sortedlist * _list_) { return _list_->count >= _list_->capacity; } size_t sl_count(struct sortedlist * _list_) { return _list_->count; } size_t sl_capacity(struct sortedlist * _list_) { return _list_->capacity; } int sl_flag(struct sortedlist * _list_) { return _list_->flag; } _Bool sl_resize(struct sortedlist * _list_, size_t capacity) { if (_list_->capacity == capacity) goto success; if (capacity < _list_->count) { _list_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _list_->flag = CMC_FLAG_ALLOC; return 0; } _list_->buffer = new_buffer; _list_->capacity = capacity; success: _list_->flag = CMC_FLAG_OK; if ((_list_)->callbacks && (_list_)->callbacks->resize) (_list_)->callbacks->resize();; return 1; } void sl_sort(struct sortedlist * _list_) { _list_->flag = CMC_FLAG_OK; if (!_list_->is_sorted && _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, ((void *)0)); if (!result) { _list_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _list_->callbacks; if (_list_->f_val->cpy) { for (size_t i = 0; i < _list_->count; i++) result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); } else memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); result->count = _list_->count; _list_->flag = CMC_FLAG_OK; return result; } _Bool sl_equals(struct sortedlist * _list1_, struct sortedlist * _list2_) { if (_list1_->count != _list2_->count) return 0; sl_sort(_list1_); sl_sort(_list2_); for (size_t i = 0; i < _list1_->count; i++) { if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) return 0; } return 1; } static size_t sl_impl_binary_search_first(struct sortedlist * _list_, size_t value) { if (sl_empty(_list_)) return 1; size_t L = 0; size_t R = _list_->count; while (L < R) { size_t M = L + (R - L) / 2; if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) L = M + 1; else R = M; } if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) return L; return _list_->count; } static size_t sl_impl_binary_search_last(struct sortedlist * _list_, size_t value) { if (sl_empty(_list_)) return 1; size_t L = 0; size_t R = _list_->count; while (L < R) { size_t M = L + (R - L) / 2; if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) R = M; else L = M + 1; } if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) return L - 1; return _list_->count; } void sl_impl_sort_quicksort(size_t * array, int (*cmp)(size_t, size_t), size_t low, size_t high) { while (low < high) { if (high - low < 10) { sl_impl_sort_insertion(array, cmp, low, high); break; } else { size_t pivot = array[high]; size_t pindex = low; for (size_t i = low; i < high; i++) { if (cmp(array[i], pivot) <= 0) { size_t _tmp_ = array[i]; array[i] = array[pindex]; array[pindex] = _tmp_; pindex++; } } size_t _tmp_ = array[pindex]; array[pindex] = array[high]; array[high] = _tmp_; if (pindex - low < high - pindex) { sl_impl_sort_quicksort (array, cmp, low, pindex - 1); low = pindex + 1; } else { sl_impl_sort_quicksort (array, cmp, pindex + 1, high); high = pindex - 1; } } } } void sl_impl_sort_insertion(size_t * array, int (*cmp)(size_t, size_t), size_t low, size_t high) { for (size_t i = low + 1; i <= high; i++) { size_t _tmp_ = array[i]; size_t j = i; while (j > low && cmp(array[j - 1], _tmp_) > 0) { array[j] = array[j - 1]; j--; } array[j] = _tmp_; } } struct sortedlist_iter sl_iter_start(struct sortedlist * target) { sl_sort(target); struct sortedlist_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = sl_empty(target); return iter; } struct sortedlist_iter sl_iter_end(struct sortedlist * target) { sl_sort(target); struct sortedlist_iter iter; iter.target = target; iter.cursor = 0; iter.start = sl_empty(target); iter.end = 1; if (!sl_empty(target)) iter.cursor = target->count - 1; return iter; } _Bool sl_iter_at_start(struct sortedlist_iter * iter) { return sl_empty(iter->target) || iter->start; } _Bool sl_iter_at_end(struct sortedlist_iter * iter) { return sl_empty(iter->target) || iter->end; } _Bool sl_iter_to_start(struct sortedlist_iter * iter) { if (!sl_empty(iter->target)) { iter->cursor = 0; iter->start = 1; iter->end = sl_empty(iter->target); return 1; } return 0; } _Bool sl_iter_to_end(struct sortedlist_iter * iter) { if (!sl_empty(iter->target)) { iter->start = sl_empty(iter->target); iter->cursor = iter->target->count - 1; iter->end = 1; return 1; } return 0; } _Bool sl_iter_next(struct sortedlist_iter * iter) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } iter->start = sl_empty(iter->target); iter->cursor++; return 1; } _Bool sl_iter_prev(struct sortedlist_iter * iter) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } iter->end = sl_empty(iter->target); iter->cursor--; return 1; } _Bool sl_iter_advance(struct sortedlist_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor + 1 == iter->target->count) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; iter->start = sl_empty(iter->target); iter->cursor += steps; return 1; } _Bool sl_iter_rewind(struct sortedlist_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == 0) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->end = sl_empty(iter->target); iter->cursor -= steps; return 1; } _Bool sl_iter_go_to(struct sortedlist_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return sl_iter_rewind(iter, iter->cursor - index); else if (iter->cursor < index) return sl_iter_advance(iter, index - iter->cursor); return 1; } size_t sl_iter_value(struct sortedlist_iter * iter) { if (sl_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t sl_iter_index(struct sortedlist_iter * iter) { return iter->cursor; } _Bool sl_to_string(struct sortedlist * _list_, FILE * fptr) { struct sortedlist *l_ = _list_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "is_sorted:%s, " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); } _Bool sl_print(struct sortedlist * _list_, FILE * fptr, const char *start, const char *separator, const char *end) { sl_sort(_list_); fprintf(fptr, "%s", start); for (size_t i = 0; i < _list_->count; i++) { if (!_list_->f_val->str(fptr, _list_->buffer[i])) return 0; if (i + 1 < _list_->count) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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) +{ + return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0)); +} +struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (capacity < 1) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist)); + if (!_list_) + return ((void *)0); + _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_list_->buffer) + { + alloc->free(_list_); + return ((void *)0); + } + _list_->capacity = capacity; + _list_->count = 0; + _list_->is_sorted = 0; + _list_->flag = CMC_FLAG_OK; + _list_->f_val = f_val; + _list_->alloc = alloc; + (_list_)->callbacks = callbacks; + return _list_; +} +void sl_clear(struct sortedlist *_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(size_t) * _list_->capacity); + _list_->count = 0; + _list_->flag = CMC_FLAG_OK; +} +void sl_free(struct sortedlist *_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 sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _list_->alloc = &cmc_alloc_node_default; + else + _list_->alloc = alloc; + (_list_)->callbacks = callbacks; + _list_->flag = CMC_FLAG_OK; +} +_Bool sl_insert(struct sortedlist *_list_, size_t value) +{ + if (sl_full(_list_)) + { + if (!sl_resize(_list_, _list_->capacity * 2)) + return 0; + } + _list_->buffer[_list_->count++] = value; + _list_->is_sorted = 0; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->create) + (_list_)->callbacks->create(); + ; + return 1; +} +_Bool sl_remove(struct sortedlist *_list_, size_t index) +{ + if (sl_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return 0; + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return 0; + } + memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); + _list_->buffer[--_list_->count] = (size_t){ 0 }; + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->delete) + (_list_)->callbacks->delete (); + ; + return 1; +} +size_t sl_max(struct sortedlist *_list_) +{ + if (sl_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + sl_sort(_list_); + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return _list_->buffer[_list_->count - 1]; +} +size_t sl_min(struct sortedlist *_list_) +{ + if (sl_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + sl_sort(_list_); + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return _list_->buffer[0]; +} +size_t sl_get(struct sortedlist *_list_, size_t index) +{ + if (sl_empty(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return (size_t){ 0 }; + } + sl_sort(_list_); + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return _list_->buffer[index]; +} +size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start) +{ + _list_->flag = CMC_FLAG_OK; + sl_sort(_list_); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + if (from_start) + { + return sl_impl_binary_search_first(_list_, value); + } + return sl_impl_binary_search_last(_list_, value); +} +_Bool sl_contains(struct sortedlist *_list_, size_t value) +{ + _list_->flag = CMC_FLAG_OK; + if (sl_empty(_list_)) + return 0; + sl_sort(_list_); + if ((_list_)->callbacks && (_list_)->callbacks->read) + (_list_)->callbacks->read(); + ; + return sl_impl_binary_search_first(_list_, value) < _list_->count; +} +_Bool sl_empty(struct sortedlist *_list_) +{ + return _list_->count == 0; +} +_Bool sl_full(struct sortedlist *_list_) +{ + return _list_->count >= _list_->capacity; +} +size_t sl_count(struct sortedlist *_list_) +{ + return _list_->count; +} +size_t sl_capacity(struct sortedlist *_list_) +{ + return _list_->capacity; +} +int sl_flag(struct sortedlist *_list_) +{ + return _list_->flag; +} +_Bool sl_resize(struct sortedlist *_list_, size_t capacity) +{ + if (_list_->capacity == capacity) + goto success; + if (capacity < _list_->count) + { + _list_->flag = CMC_FLAG_INVALID; + return 0; + } + size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); + if (!new_buffer) + { + _list_->flag = CMC_FLAG_ALLOC; + return 0; + } + _list_->buffer = new_buffer; + _list_->capacity = capacity; +success: + _list_->flag = CMC_FLAG_OK; + if ((_list_)->callbacks && (_list_)->callbacks->resize) + (_list_)->callbacks->resize(); + ; + return 1; +} +void sl_sort(struct sortedlist *_list_) +{ + _list_->flag = CMC_FLAG_OK; + if (!_list_->is_sorted && _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, ((void *)0)); + if (!result) + { + _list_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _list_->callbacks; + if (_list_->f_val->cpy) + { + for (size_t i = 0; i < _list_->count; i++) + result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); + } + else + memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); + result->count = _list_->count; + _list_->flag = CMC_FLAG_OK; + return result; +} +_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_) +{ + if (_list1_->count != _list2_->count) + return 0; + sl_sort(_list1_); + sl_sort(_list2_); + for (size_t i = 0; i < _list1_->count; i++) + { + if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) + return 0; + } + return 1; +} +static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value) +{ + if (sl_empty(_list_)) + return 1; + size_t L = 0; + size_t R = _list_->count; + while (L < R) + { + size_t M = L + (R - L) / 2; + if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) + L = M + 1; + else + R = M; + } + if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) + return L; + return _list_->count; +} +static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value) +{ + if (sl_empty(_list_)) + return 1; + size_t L = 0; + size_t R = _list_->count; + while (L < R) + { + size_t M = L + (R - L) / 2; + if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) + R = M; + else + L = M + 1; + } + if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) + return L - 1; + return _list_->count; +} +void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) +{ + while (low < high) + { + if (high - low < 10) + { + sl_impl_sort_insertion(array, cmp, low, high); + break; + } + else + { + size_t pivot = array[high]; + size_t pindex = low; + for (size_t i = low; i < high; i++) + { + if (cmp(array[i], pivot) <= 0) + { + size_t _tmp_ = array[i]; + array[i] = array[pindex]; + array[pindex] = _tmp_; + pindex++; + } + } + size_t _tmp_ = array[pindex]; + array[pindex] = array[high]; + array[high] = _tmp_; + if (pindex - low < high - pindex) + { + sl_impl_sort_quicksort(array, cmp, low, pindex - 1); + low = pindex + 1; + } + else + { + sl_impl_sort_quicksort(array, cmp, pindex + 1, high); + high = pindex - 1; + } + } + } +} +void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) +{ + for (size_t i = low + 1; i <= high; i++) + { + size_t _tmp_ = array[i]; + size_t j = i; + while (j > low && cmp(array[j - 1], _tmp_) > 0) + { + array[j] = array[j - 1]; + j--; + } + array[j] = _tmp_; + } +} +struct sortedlist_iter sl_iter_start(struct sortedlist *target) +{ + sl_sort(target); + struct sortedlist_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = sl_empty(target); + return iter; +} +struct sortedlist_iter sl_iter_end(struct sortedlist *target) +{ + sl_sort(target); + struct sortedlist_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = sl_empty(target); + iter.end = 1; + if (!sl_empty(target)) + iter.cursor = target->count - 1; + return iter; +} +_Bool sl_iter_at_start(struct sortedlist_iter *iter) +{ + return sl_empty(iter->target) || iter->start; +} +_Bool sl_iter_at_end(struct sortedlist_iter *iter) +{ + return sl_empty(iter->target) || iter->end; +} +_Bool sl_iter_to_start(struct sortedlist_iter *iter) +{ + if (!sl_empty(iter->target)) + { + iter->cursor = 0; + iter->start = 1; + iter->end = sl_empty(iter->target); + return 1; + } + return 0; +} +_Bool sl_iter_to_end(struct sortedlist_iter *iter) +{ + if (!sl_empty(iter->target)) + { + iter->start = sl_empty(iter->target); + iter->cursor = iter->target->count - 1; + iter->end = 1; + return 1; + } + return 0; +} +_Bool sl_iter_next(struct sortedlist_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + iter->start = sl_empty(iter->target); + iter->cursor++; + return 1; +} +_Bool sl_iter_prev(struct sortedlist_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + iter->end = sl_empty(iter->target); + iter->cursor--; + return 1; +} +_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return 0; + iter->start = sl_empty(iter->target); + iter->cursor += steps; + return 1; +} +_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor == 0) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->cursor < steps) + return 0; + iter->end = sl_empty(iter->target); + iter->cursor -= steps; + return 1; +} +_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->cursor > index) + return sl_iter_rewind(iter, iter->cursor - index); + else if (iter->cursor < index) + return sl_iter_advance(iter, index - iter->cursor); + return 1; +} +size_t sl_iter_value(struct sortedlist_iter *iter) +{ + if (sl_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor]; +} +size_t sl_iter_index(struct sortedlist_iter *iter) +{ + return iter->cursor; +} +_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr) +{ + struct sortedlist *l_ = _list_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "is_sorted:%s, " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count, + l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); +} +_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + sl_sort(_list_); + fprintf(fptr, "%s", start); + for (size_t i = 0; i < _list_->count; i++) + { + if (!_list_->f_val->str(fptr, _list_->buffer[i])) + return 0; + if (i + 1 < _list_->count) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_stack.c b/tests/src/tst_cmc_stack.c index 16f8bf8..e6030a3 100644 --- a/tests/src/tst_cmc_stack.c +++ b/tests/src/tst_cmc_stack.c @@ -1,7 +1,367 @@ - #include "tst_cmc_stack.h" +#include "tst_cmc_stack.h" - - struct stack *s_new(size_t capacity, struct stack_fval * f_val) { return s_new_custom(capacity, f_val, ((void *)0), ((void *)0)); } struct stack *s_new_custom(size_t capacity, struct stack_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (capacity < 1) return ((void *)0); if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct stack *_stack_ = alloc->malloc(sizeof(struct stack)); if (!_stack_) return ((void *)0); _stack_->buffer = alloc->calloc(capacity, sizeof(size_t)); if (!_stack_->buffer) { alloc->free(_stack_); return ((void *)0); } _stack_->capacity = capacity; _stack_->count = 0; _stack_->flag = CMC_FLAG_OK; _stack_->f_val = f_val; _stack_->alloc = alloc; (_stack_)->callbacks = callbacks; return _stack_; } void s_clear(struct stack * _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(size_t) * _stack_->capacity); _stack_->count = 0; _stack_->flag = CMC_FLAG_OK; } void s_free(struct stack * _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 s_customize(struct stack * _stack_, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!alloc) _stack_->alloc = &cmc_alloc_node_default; else _stack_->alloc = alloc; (_stack_)->callbacks = callbacks; _stack_->flag = CMC_FLAG_OK; } _Bool s_push(struct stack * _stack_, size_t value) { if (s_full(_stack_)) { if (!s_resize(_stack_, _stack_->capacity * 2)) return 0; } _stack_->buffer[_stack_->count++] = value; _stack_->flag = CMC_FLAG_OK; if ((_stack_)->callbacks && (_stack_)->callbacks->create) (_stack_)->callbacks->create();; return 1; } _Bool s_pop(struct stack * _stack_) { if (s_empty(_stack_)) { _stack_->flag = CMC_FLAG_EMPTY; return 0; } _stack_->buffer[--_stack_->count] = (size_t){ 0 }; _stack_->flag = CMC_FLAG_OK; if ((_stack_)->callbacks && (_stack_)->callbacks->delete) (_stack_)->callbacks->delete();; return 1; } size_t s_top(struct stack * _stack_) { if (s_empty(_stack_)) { _stack_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } _stack_->flag = CMC_FLAG_OK; if ((_stack_)->callbacks && (_stack_)->callbacks->read) (_stack_)->callbacks->read();; return _stack_->buffer[_stack_->count - 1]; } _Bool s_contains(struct stack * _stack_, size_t value) { _stack_->flag = CMC_FLAG_OK; _Bool result = 0; for (size_t i = 0; i < _stack_->count; i++) { if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) { result = 1; break; } } if ((_stack_)->callbacks && (_stack_)->callbacks->read) (_stack_)->callbacks->read();; return result; } _Bool s_empty(struct stack * _stack_) { return _stack_->count == 0; } _Bool s_full(struct stack * _stack_) { return _stack_->count >= _stack_->capacity; } size_t s_count(struct stack * _stack_) { return _stack_->count; } size_t s_capacity(struct stack * _stack_) { return _stack_->capacity; } int s_flag(struct stack * _stack_) { return _stack_->flag; } _Bool s_resize(struct stack * _stack_, size_t capacity) { if (_stack_->capacity == capacity) goto success; if (capacity < _stack_->count) { _stack_->flag = CMC_FLAG_INVALID; return 0; } size_t *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity); if (!new_buffer) { _stack_->flag = CMC_FLAG_ALLOC; return 0; } _stack_->buffer = new_buffer; _stack_->capacity = capacity; success: _stack_->flag = CMC_FLAG_OK; if ((_stack_)->callbacks && (_stack_)->callbacks->resize) (_stack_)->callbacks->resize();; return 1; } struct stack *s_copy_of(struct stack * _stack_) { struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0)); if (!result) { _stack_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _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(size_t) * _stack_->count); result->count = _stack_->count; _stack_->flag = CMC_FLAG_OK; return result; } _Bool s_equals(struct stack * _stack1_, struct stack * _stack2_) { _stack1_->flag = CMC_FLAG_OK; _stack2_->flag = CMC_FLAG_OK; if (_stack1_->count != _stack2_->count) return 0; for (size_t i = 0; i < _stack1_->count; i++) { if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) return 0; } return 1; } struct stack_iter s_iter_start(struct stack * target) { struct stack_iter iter; iter.target = target; iter.cursor = 0; iter.start = 1; iter.end = s_empty(target); if (!s_empty(target)) iter.cursor = target->count - 1; return iter; } struct stack_iter s_iter_end(struct stack * target) { struct stack_iter iter; iter.target = target; iter.cursor = 0; iter.start = s_empty(target); iter.end = 1; return iter; } _Bool s_iter_at_start(struct stack_iter * iter) { return s_empty(iter->target) || iter->start; } _Bool s_iter_at_end(struct stack_iter * iter) { return s_empty(iter->target) || iter->end; } _Bool s_iter_to_start(struct stack_iter * iter) { if (!s_empty(iter->target)) { iter->cursor = iter->target->count - 1; iter->start = 1; iter->end = s_empty(iter->target); return 1; } return 0; } _Bool s_iter_to_end(struct stack_iter * iter) { if (!s_empty(iter->target)) { iter->cursor = 0; iter->start = s_empty(iter->target); iter->end = 1; return 1; } return 0; } _Bool s_iter_next(struct stack_iter * iter) { if (iter->end) return 0; if (iter->cursor == 0) { iter->end = 1; return 0; } iter->start = s_empty(iter->target); iter->cursor--; return 1; } _Bool s_iter_prev(struct stack_iter * iter) { if (iter->start) return 0; if (iter->cursor + 1 == iter->target->count) { iter->start = 1; return 0; } iter->end = s_empty(iter->target); iter->cursor++; return 1; } _Bool s_iter_advance(struct stack_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor == 0) { iter->end = 1; return 0; } if (steps == 0 || iter->cursor < steps) return 0; iter->start = s_empty(iter->target); iter->cursor -= steps; return 1; } _Bool s_iter_rewind(struct stack_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor + 1 == iter->target->count) { iter->start = 1; return 0; } if (steps == 0 || iter->cursor + steps >= iter->target->count) return 0; iter->end = s_empty(iter->target); iter->cursor += steps; return 1; } _Bool s_iter_go_to(struct stack_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->cursor > index) return s_iter_advance(iter, iter->cursor - index); else if (iter->cursor < index) return s_iter_rewind(iter, index - iter->cursor); return 1; } size_t s_iter_value(struct stack_iter * iter) { if (s_empty(iter->target)) return (size_t){ 0 }; return iter->target->buffer[iter->cursor]; } size_t *s_iter_rvalue(struct stack_iter * iter) { if (s_empty(iter->target)) return ((void *)0); return &(iter->target->buffer[iter->cursor]); } size_t s_iter_index(struct stack_iter * iter) { if (s_empty(iter->target)) return 0; return iter->target->count - 1 - iter->cursor; } _Bool s_to_string(struct stack * _stack_, FILE * fptr) { struct stack *s_ = _stack_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "buffer:%p, " "capacity:%" "I64u" ", " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); } _Bool s_print(struct stack * _stack_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); for (size_t i = _stack_->count; i > 0; i--) { if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) return 0; if (i - 1 != 0) fprintf(fptr, "%s", separator); } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +struct stack *s_new(size_t capacity, struct stack_fval *f_val) +{ + return s_new_custom(capacity, f_val, ((void *)0), ((void *)0)); +} +struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (capacity < 1) + return ((void *)0); + if (!f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct stack *_stack_ = alloc->malloc(sizeof(struct stack)); + if (!_stack_) + return ((void *)0); + _stack_->buffer = alloc->calloc(capacity, sizeof(size_t)); + if (!_stack_->buffer) + { + alloc->free(_stack_); + return ((void *)0); + } + _stack_->capacity = capacity; + _stack_->count = 0; + _stack_->flag = CMC_FLAG_OK; + _stack_->f_val = f_val; + _stack_->alloc = alloc; + (_stack_)->callbacks = callbacks; + return _stack_; +} +void s_clear(struct stack *_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(size_t) * _stack_->capacity); + _stack_->count = 0; + _stack_->flag = CMC_FLAG_OK; +} +void s_free(struct stack *_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 s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!alloc) + _stack_->alloc = &cmc_alloc_node_default; + else + _stack_->alloc = alloc; + (_stack_)->callbacks = callbacks; + _stack_->flag = CMC_FLAG_OK; +} +_Bool s_push(struct stack *_stack_, size_t value) +{ + if (s_full(_stack_)) + { + if (!s_resize(_stack_, _stack_->capacity * 2)) + return 0; + } + _stack_->buffer[_stack_->count++] = value; + _stack_->flag = CMC_FLAG_OK; + if ((_stack_)->callbacks && (_stack_)->callbacks->create) + (_stack_)->callbacks->create(); + ; + return 1; +} +_Bool s_pop(struct stack *_stack_) +{ + if (s_empty(_stack_)) + { + _stack_->flag = CMC_FLAG_EMPTY; + return 0; + } + _stack_->buffer[--_stack_->count] = (size_t){ 0 }; + _stack_->flag = CMC_FLAG_OK; + if ((_stack_)->callbacks && (_stack_)->callbacks->delete) + (_stack_)->callbacks->delete (); + ; + return 1; +} +size_t s_top(struct stack *_stack_) +{ + if (s_empty(_stack_)) + { + _stack_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + _stack_->flag = CMC_FLAG_OK; + if ((_stack_)->callbacks && (_stack_)->callbacks->read) + (_stack_)->callbacks->read(); + ; + return _stack_->buffer[_stack_->count - 1]; +} +_Bool s_contains(struct stack *_stack_, size_t value) +{ + _stack_->flag = CMC_FLAG_OK; + _Bool result = 0; + for (size_t i = 0; i < _stack_->count; i++) + { + if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) + { + result = 1; + break; + } + } + if ((_stack_)->callbacks && (_stack_)->callbacks->read) + (_stack_)->callbacks->read(); + ; + return result; +} +_Bool s_empty(struct stack *_stack_) +{ + return _stack_->count == 0; +} +_Bool s_full(struct stack *_stack_) +{ + return _stack_->count >= _stack_->capacity; +} +size_t s_count(struct stack *_stack_) +{ + return _stack_->count; +} +size_t s_capacity(struct stack *_stack_) +{ + return _stack_->capacity; +} +int s_flag(struct stack *_stack_) +{ + return _stack_->flag; +} +_Bool s_resize(struct stack *_stack_, size_t capacity) +{ + if (_stack_->capacity == capacity) + goto success; + if (capacity < _stack_->count) + { + _stack_->flag = CMC_FLAG_INVALID; + return 0; + } + size_t *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity); + if (!new_buffer) + { + _stack_->flag = CMC_FLAG_ALLOC; + return 0; + } + _stack_->buffer = new_buffer; + _stack_->capacity = capacity; +success: + _stack_->flag = CMC_FLAG_OK; + if ((_stack_)->callbacks && (_stack_)->callbacks->resize) + (_stack_)->callbacks->resize(); + ; + return 1; +} +struct stack *s_copy_of(struct stack *_stack_) +{ + struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0)); + if (!result) + { + _stack_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _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(size_t) * _stack_->count); + result->count = _stack_->count; + _stack_->flag = CMC_FLAG_OK; + return result; +} +_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_) +{ + _stack1_->flag = CMC_FLAG_OK; + _stack2_->flag = CMC_FLAG_OK; + if (_stack1_->count != _stack2_->count) + return 0; + for (size_t i = 0; i < _stack1_->count; i++) + { + if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) + return 0; + } + return 1; +} +struct stack_iter s_iter_start(struct stack *target) +{ + struct stack_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = 1; + iter.end = s_empty(target); + if (!s_empty(target)) + iter.cursor = target->count - 1; + return iter; +} +struct stack_iter s_iter_end(struct stack *target) +{ + struct stack_iter iter; + iter.target = target; + iter.cursor = 0; + iter.start = s_empty(target); + iter.end = 1; + return iter; +} +_Bool s_iter_at_start(struct stack_iter *iter) +{ + return s_empty(iter->target) || iter->start; +} +_Bool s_iter_at_end(struct stack_iter *iter) +{ + return s_empty(iter->target) || iter->end; +} +_Bool s_iter_to_start(struct stack_iter *iter) +{ + if (!s_empty(iter->target)) + { + iter->cursor = iter->target->count - 1; + iter->start = 1; + iter->end = s_empty(iter->target); + return 1; + } + return 0; +} +_Bool s_iter_to_end(struct stack_iter *iter) +{ + if (!s_empty(iter->target)) + { + iter->cursor = 0; + iter->start = s_empty(iter->target); + iter->end = 1; + return 1; + } + return 0; +} +_Bool s_iter_next(struct stack_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor == 0) + { + iter->end = 1; + return 0; + } + iter->start = s_empty(iter->target); + iter->cursor--; + return 1; +} +_Bool s_iter_prev(struct stack_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->start = 1; + return 0; + } + iter->end = s_empty(iter->target); + iter->cursor++; + return 1; +} +_Bool s_iter_advance(struct stack_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor == 0) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->cursor < steps) + return 0; + iter->start = s_empty(iter->target); + iter->cursor -= steps; + return 1; +} +_Bool s_iter_rewind(struct stack_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor + 1 == iter->target->count) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return 0; + iter->end = s_empty(iter->target); + iter->cursor += steps; + return 1; +} +_Bool s_iter_go_to(struct stack_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->cursor > index) + return s_iter_advance(iter, iter->cursor - index); + else if (iter->cursor < index) + return s_iter_rewind(iter, index - iter->cursor); + return 1; +} +size_t s_iter_value(struct stack_iter *iter) +{ + if (s_empty(iter->target)) + return (size_t){ 0 }; + return iter->target->buffer[iter->cursor]; +} +size_t *s_iter_rvalue(struct stack_iter *iter) +{ + if (s_empty(iter->target)) + return ((void *)0); + return &(iter->target->buffer[iter->cursor]); +} +size_t s_iter_index(struct stack_iter *iter) +{ + if (s_empty(iter->target)) + return 0; + return iter->target->count - 1 - iter->cursor; +} +_Bool s_to_string(struct stack *_stack_, FILE *fptr) +{ + struct stack *s_ = _stack_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" + "I64u" + ", " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, + (s_)->callbacks); +} +_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + for (size_t i = _stack_->count; i > 0; i--) + { + if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) + return 0; + if (i - 1 != 0) + fprintf(fptr, "%s", separator); + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_treemap.c b/tests/src/tst_cmc_treemap.c index b6e2f5c..ed28e22 100644 --- a/tests/src/tst_cmc_treemap.c +++ b/tests/src/tst_cmc_treemap.c @@ -1,7 +1,852 @@ - #include "tst_cmc_treemap.h" +#include "tst_cmc_treemap.h" - - 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); static void tm_impl_rotate_right(struct treemap_node * *Z); static void tm_impl_rotate_left(struct treemap_node * *Z); static void tm_impl_rebalance(struct treemap * _map_, struct treemap_node * node); struct treemap *tm_new(struct treemap_fkey * f_key, struct treemap_fval * f_val) { return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0)); } struct treemap *tm_new_custom(struct treemap_fkey * f_key, struct treemap_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!f_key || !f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct treemap *_map_ = alloc->malloc(sizeof(struct treemap)); if (!_map_) return ((void *)0); _map_->count = 0; _map_->root = ((void *)0); _map_->flag = CMC_FLAG_OK; _map_->f_key = f_key; _map_->f_val = f_val; _map_->alloc = alloc; (_map_)->callbacks = callbacks; return _map_; } void tm_clear(struct treemap * _map_) { struct treemap_node *scan = _map_->root; struct treemap_node *up = ((void *)0); while (scan != ((void *)0)) { if (scan->left != ((void *)0)) { struct treemap_node *left = scan->left; scan->left = up; up = scan; scan = left; } else if (scan->right != ((void *)0)) { struct treemap_node *right = scan->right; scan->left = up; scan->right = ((void *)0); up = scan; scan = right; } else { if (up == ((void *)0)) { 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 = ((void *)0); } while (up != ((void *)0)) { 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 != ((void *)0)) { scan = up->right; up->right = ((void *)0); break; } else { scan = up; up = up->left; } } } } _map_->count = 0; _map_->root = ((void *)0); _map_->flag = CMC_FLAG_OK; } 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) { ; if (!alloc) _map_->alloc = &cmc_alloc_node_default; else _map_->alloc = alloc; (_map_)->callbacks = callbacks; _map_->flag = CMC_FLAG_OK; } _Bool tm_insert(struct treemap * _map_, size_t key, size_t value) { if (tm_empty(_map_)) { _map_->root = tm_impl_new_node(_map_, key, value); if (!_map_->root) { _map_->flag = CMC_FLAG_ALLOC; return 0; } } else { struct treemap_node *scan = _map_->root; struct treemap_node *parent = scan; while (scan != ((void *)0)) { 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 0; } } struct treemap_node * node; if (_map_->f_key->cmp(parent->key, key) > 0) { parent->left = tm_impl_new_node(_map_, key, value); if (!parent->left) { _map_->flag = CMC_FLAG_ALLOC; return 0; } parent->left->parent = parent; node = parent->left; } else { parent->right = tm_impl_new_node(_map_, key, value); if (!parent->right) { _map_->flag = CMC_FLAG_ALLOC; return 0; } parent->right->parent = parent; node = parent->right; } tm_impl_rebalance(_map_, node); } _map_->count++; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->create) (_map_)->callbacks->create();; return 1; } _Bool tm_update(struct treemap * _map_, size_t key, size_t new_value, size_t * old_value) { struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } 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 1; } _Bool tm_remove(struct treemap * _map_, size_t key, size_t * out_value) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } if (out_value) *out_value = node->value; struct treemap_node *temp = ((void *)0), *unbalanced = ((void *)0); _Bool is_root = node->parent == ((void *)0); if (node->left == ((void *)0) && node->right == ((void *)0)) { if (is_root) _map_->root = ((void *)0); else { unbalanced = node->parent; if (node->parent->right == node) node->parent->right = ((void *)0); else node->parent->left = ((void *)0); } _map_->alloc->free(node); } else if (node->left == ((void *)0)) { if (is_root) { _map_->root = node->right; _map_->root->parent = ((void *)0); } 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 == ((void *)0)) { if (is_root) { _map_->root = node->left; _map_->root->parent = ((void *)0); } 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 != ((void *)0)) temp = temp->left; size_t temp_key = temp->key; size_t temp_val = temp->value; unbalanced = temp->parent; if (temp->left == ((void *)0) && temp->right == ((void *)0)) { if (temp->parent->right == temp) temp->parent->right = ((void *)0); else temp->parent->left = ((void *)0); } else if (temp->left == ((void *)0)) { 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 == ((void *)0)) { 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 != ((void *)0)) tm_impl_rebalance(_map_, unbalanced); if (_map_->count == 0) _map_->root = ((void *)0); _map_->count--; _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->delete) (_map_)->callbacks->delete();; return 1; } _Bool tm_max(struct treemap * _map_, size_t * key, size_t * value) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *scan = _map_->root; while (scan->right != ((void *)0)) 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 1; } _Bool tm_min(struct treemap * _map_, size_t * key, size_t * value) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return 0; } struct treemap_node *scan = _map_->root; while (scan->left != ((void *)0)) 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 1; } size_t tm_get(struct treemap * _map_, size_t key) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return (size_t){ 0 }; } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { _map_->flag = CMC_FLAG_NOT_FOUND; return (size_t){ 0 }; } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return node->value; } size_t *tm_get_ref(struct treemap * _map_, size_t key) { if (tm_empty(_map_)) { _map_->flag = CMC_FLAG_EMPTY; return ((void *)0); } struct treemap_node *node = tm_impl_get_node(_map_, key); if (!node) { _map_->flag = CMC_FLAG_NOT_FOUND; return ((void *)0); } _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return &(node->value); } _Bool tm_contains(struct treemap * _map_, size_t key) { _Bool result = tm_impl_get_node(_map_, key) != ((void *)0); if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read();; return result; } _Bool tm_empty(struct treemap * _map_) { return _map_->count == 0; } size_t tm_count(struct treemap * _map_) { return _map_->count; } int tm_flag(struct treemap * _map_) { return _map_->flag; } struct treemap *tm_copy_of(struct treemap * _map_) { struct treemap *result = tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); if (!result) { _map_->flag = CMC_FLAG_ERROR; return ((void *)0); } struct treemap_node *root = _map_->root; _Bool left_done = 0; while (root) { if (!left_done) { while (root->left) root = root->left; } size_t key; size_t value; if (_map_->f_key->cpy) key = _map_->f_key->cpy(root->key); else key = root->key; if (_map_->f_val->cpy) value = _map_->f_val->cpy(root->value); else value = root->value; tm_insert(result, key, value); 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; } _map_->flag = CMC_FLAG_OK; (result)->callbacks = _map_->callbacks; return result; } _Bool tm_equals(struct treemap * _map1_, struct treemap * _map2_) { _map1_->flag = CMC_FLAG_OK; _map2_->flag = CMC_FLAG_OK; if (_map1_->count != _map2_->count) return 0; struct treemap_node *root = _map1_->root; _Bool left_done = 0; while (root) { if (!left_done) { while (root->left) root = root->left; } struct treemap_node *node = tm_impl_get_node(_map2_, root->key); if (node == ((void *)0)) return 0; if (_map1_->f_val->cmp(node->value, root->value) != 0) 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; } static struct treemap_node * tm_impl_new_node(struct treemap * _map_, size_t key, size_t value) { struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); if (!node) return ((void *)0); node->key = key; node->value = value; node->right = ((void *)0); node->left = ((void *)0); node->parent = ((void *)0); node->height = 0; return node; } static struct treemap_node * tm_impl_get_node(struct treemap * _map_, size_t key) { struct treemap_node *scan = _map_->root; while (scan != ((void *)0)) { if (_map_->f_key->cmp(scan->key, key) > 0) scan = scan->left; else if (_map_->f_key->cmp(scan->key, key) < 0) scan = scan->right; else return scan; } return ((void *)0); } static unsigned char tm_impl_h(struct treemap_node * node) { if (node == ((void *)0)) return 0; return node->height; } static unsigned char tm_impl_hupdate(struct treemap_node * node) { if (node == ((void *)0)) return 0; unsigned char h_l = tm_impl_h(node->left); unsigned char h_r = tm_impl_h(node->right); return 1 + (h_l > h_r ? h_l : h_r); } static void tm_impl_rotate_right(struct treemap_node * *Z) { struct treemap_node *root = *Z; struct treemap_node *new_root = root->left; if (root->parent != ((void *)0)) { if (root->parent->left == root) root->parent->left = new_root; else root->parent->right = new_root; } new_root->parent = root->parent; root->parent = new_root; root->left = new_root->right; if (root->left) root->left->parent = root; new_root->right = root; root->height = tm_impl_hupdate(root); new_root->height = tm_impl_hupdate(new_root); *Z = new_root; } static void tm_impl_rotate_left(struct treemap_node * *Z) { struct treemap_node *root = *Z; struct treemap_node *new_root = root->right; if (root->parent != ((void *)0)) { if (root->parent->right == root) root->parent->right = new_root; else root->parent->left = new_root; } new_root->parent = root->parent; root->parent = new_root; root->right = new_root->left; if (root->right) root->right->parent = root; new_root->left = root; root->height = tm_impl_hupdate(root); new_root->height = tm_impl_hupdate(new_root); *Z = new_root; } static void tm_impl_rebalance(struct treemap * _map_, struct treemap_node * node) { struct treemap_node *scan = node, *child = ((void *)0); int balance; _Bool is_root = 0; while (scan != ((void *)0)) { if (scan->parent == ((void *)0)) is_root = 1; scan->height = tm_impl_hupdate(scan); balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); if (balance >= 2) { child = scan->right; if (tm_impl_h(child->right) < tm_impl_h(child->left)) tm_impl_rotate_right(&(scan->right)); tm_impl_rotate_left(&scan); } else if (balance <= -2) { child = scan->left; if (tm_impl_h(child->left) < tm_impl_h(child->right)) tm_impl_rotate_left(&(scan->left)); tm_impl_rotate_right(&scan); } if (is_root) { _map_->root = scan; is_root = 0; } scan = scan->parent; } } struct treemap_iter tm_iter_start(struct treemap * target) { struct treemap_iter iter; iter.target = target; iter.cursor = target->root; iter.first = ((void *)0); iter.last = ((void *)0); iter.index = 0; iter.start = 1; iter.end = tm_empty(target); if (!tm_empty(target)) { while (iter.cursor->left != ((void *)0)) iter.cursor = iter.cursor->left; iter.first = iter.cursor; iter.last = target->root; while (iter.last->right != ((void *)0)) iter.last = iter.last->right; } return iter; } struct treemap_iter tm_iter_end(struct treemap * target) { struct treemap_iter iter; iter.target = target; iter.cursor = target->root; iter.first = ((void *)0); iter.last = ((void *)0); iter.index = 0; iter.start = tm_empty(target); iter.end = 1; if (!tm_empty(target)) { while (iter.cursor->right != ((void *)0)) iter.cursor = iter.cursor->right; iter.last = iter.cursor; iter.first = target->root; while (iter.first->left != ((void *)0)) iter.first = iter.first->left; iter.index = target->count - 1; } return iter; } _Bool tm_iter_at_start(struct treemap_iter * iter) { return tm_empty(iter->target) || iter->start; } _Bool tm_iter_at_end(struct treemap_iter * iter) { return tm_empty(iter->target) || iter->end; } _Bool tm_iter_to_start(struct treemap_iter * iter) { if (!tm_empty(iter->target)) { iter->index = 0; iter->start = 1; iter->end = tm_empty(iter->target); iter->cursor = iter->first; return 1; } return 0; } _Bool tm_iter_to_end(struct treemap_iter * iter) { if (!tm_empty(iter->target)) { iter->index = iter->target->count - 1; iter->start = tm_empty(iter->target); iter->end = 1; iter->cursor = iter->last; return 1; } return 0; } _Bool tm_iter_next(struct treemap_iter * iter) { if (iter->end) return 0; if (iter->cursor == iter->last) { iter->end = 1; return 0; } iter->start = tm_empty(iter->target); if (iter->cursor->right != ((void *)0)) { iter->cursor = iter->cursor->right; while (iter->cursor->left != ((void *)0)) iter->cursor = iter->cursor->left; iter->index++; return 1; } while (1) { if (iter->cursor->parent->left == iter->cursor) { iter->cursor = iter->cursor->parent; iter->index++; return 1; } iter->cursor = iter->cursor->parent; } } _Bool tm_iter_prev(struct treemap_iter * iter) { if (iter->start) return 0; if (iter->cursor == iter->first) { iter->start = 1; return 0; } iter->end = tm_empty(iter->target); if (iter->cursor->left != ((void *)0)) { iter->cursor = iter->cursor->left; while (iter->cursor->right != ((void *)0)) iter->cursor = iter->cursor->right; iter->index--; return 1; } while (1) { if (iter->cursor->parent->right == iter->cursor) { iter->cursor = iter->cursor->parent; iter->index--; return 1; } iter->cursor = iter->cursor->parent; } } _Bool tm_iter_advance(struct treemap_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor == iter->last) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) tm_iter_next(iter); return 1; } _Bool tm_iter_rewind(struct treemap_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == iter->first) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) tm_iter_prev(iter); return 1; } _Bool tm_iter_go_to(struct treemap_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return tm_iter_rewind(iter, iter->index - index); else if (iter->index < index) return tm_iter_advance(iter, index - iter->index); return 1; } size_t tm_iter_key(struct treemap_iter * iter) { if (tm_empty(iter->target)) return (size_t){ 0 }; return iter->cursor->key; } size_t tm_iter_value(struct treemap_iter * iter) { if (tm_empty(iter->target)) return (size_t){ 0 }; return iter->cursor->value; } size_t *tm_iter_rvalue(struct treemap_iter * iter) { if (tm_empty(iter->target)) return ((void *)0); return &(iter->cursor->value); } size_t tm_iter_index(struct treemap_iter * iter) { return iter->index; } _Bool tm_to_string(struct treemap * _map_, FILE * fptr) { struct treemap *m_ = _map_; return 0 <= fprintf(fptr, "struct %s<%s, %s> " "at %p { " "root:%p, " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "f_key:%p, " "alloc:%p, " "callbacks:%p }", "treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); } _Bool tm_print(struct treemap * _map_, FILE * fptr, const char *start, const char *separator, const char *end, const char *key_val_sep) { fprintf(fptr, "%s", start); struct treemap_node *root = _map_->root; _Bool left_done = 0; size_t i = 0; while (root) { if (!left_done) { while (root->left) root = root->left; } if (!_map_->f_key->str(fptr, root->key)) return 0; fprintf(fptr, "%s", key_val_sep); if (!_map_->f_val->str(fptr, root->value)) return 0; if (++i < _map_->count) fprintf(fptr, "%s", separator); left_done = 1; if (root->right) { left_done = 0; root = root->right; } else if (root->parent) { while (root->parent && root == root->parent->right) root = root->parent; if (!root->parent) break; root = root->parent; } else break; } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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); +static void tm_impl_rotate_right(struct treemap_node **Z); +static void tm_impl_rotate_left(struct treemap_node **Z); +static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node); +struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val) +{ + return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0)); +} +struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, + struct cmc_callbacks *callbacks) +{ + ; + if (!f_key || !f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct treemap *_map_ = alloc->malloc(sizeof(struct treemap)); + if (!_map_) + return ((void *)0); + _map_->count = 0; + _map_->root = ((void *)0); + _map_->flag = CMC_FLAG_OK; + _map_->f_key = f_key; + _map_->f_val = f_val; + _map_->alloc = alloc; + (_map_)->callbacks = callbacks; + return _map_; +} +void tm_clear(struct treemap *_map_) +{ + struct treemap_node *scan = _map_->root; + struct treemap_node *up = ((void *)0); + while (scan != ((void *)0)) + { + if (scan->left != ((void *)0)) + { + struct treemap_node *left = scan->left; + scan->left = up; + up = scan; + scan = left; + } + else if (scan->right != ((void *)0)) + { + struct treemap_node *right = scan->right; + scan->left = up; + scan->right = ((void *)0); + up = scan; + scan = right; + } + else + { + if (up == ((void *)0)) + { + 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 = ((void *)0); + } + while (up != ((void *)0)) + { + 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 != ((void *)0)) + { + scan = up->right; + up->right = ((void *)0); + break; + } + else + { + scan = up; + up = up->left; + } + } + } + } + _map_->count = 0; + _map_->root = ((void *)0); + _map_->flag = CMC_FLAG_OK; +} +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) +{ + ; + if (!alloc) + _map_->alloc = &cmc_alloc_node_default; + else + _map_->alloc = alloc; + (_map_)->callbacks = callbacks; + _map_->flag = CMC_FLAG_OK; +} +_Bool tm_insert(struct treemap *_map_, size_t key, size_t value) +{ + if (tm_empty(_map_)) + { + _map_->root = tm_impl_new_node(_map_, key, value); + if (!_map_->root) + { + _map_->flag = CMC_FLAG_ALLOC; + return 0; + } + } + else + { + struct treemap_node *scan = _map_->root; + struct treemap_node *parent = scan; + while (scan != ((void *)0)) + { + 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 0; + } + } + struct treemap_node *node; + if (_map_->f_key->cmp(parent->key, key) > 0) + { + parent->left = tm_impl_new_node(_map_, key, value); + if (!parent->left) + { + _map_->flag = CMC_FLAG_ALLOC; + return 0; + } + parent->left->parent = parent; + node = parent->left; + } + else + { + parent->right = tm_impl_new_node(_map_, key, value); + if (!parent->right) + { + _map_->flag = CMC_FLAG_ALLOC; + return 0; + } + parent->right->parent = parent; + node = parent->right; + } + tm_impl_rebalance(_map_, node); + } + _map_->count++; + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->create) + (_map_)->callbacks->create(); + ; + return 1; +} +_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value) +{ + struct treemap_node *node = tm_impl_get_node(_map_, key); + if (!node) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + 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 1; +} +_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) +{ + if (tm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct treemap_node *node = tm_impl_get_node(_map_, key); + if (!node) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + if (out_value) + *out_value = node->value; + struct treemap_node *temp = ((void *)0), *unbalanced = ((void *)0); + _Bool is_root = node->parent == ((void *)0); + if (node->left == ((void *)0) && node->right == ((void *)0)) + { + if (is_root) + _map_->root = ((void *)0); + else + { + unbalanced = node->parent; + if (node->parent->right == node) + node->parent->right = ((void *)0); + else + node->parent->left = ((void *)0); + } + _map_->alloc->free(node); + } + else if (node->left == ((void *)0)) + { + if (is_root) + { + _map_->root = node->right; + _map_->root->parent = ((void *)0); + } + 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 == ((void *)0)) + { + if (is_root) + { + _map_->root = node->left; + _map_->root->parent = ((void *)0); + } + 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 != ((void *)0)) + temp = temp->left; + size_t temp_key = temp->key; + size_t temp_val = temp->value; + unbalanced = temp->parent; + if (temp->left == ((void *)0) && temp->right == ((void *)0)) + { + if (temp->parent->right == temp) + temp->parent->right = ((void *)0); + else + temp->parent->left = ((void *)0); + } + else if (temp->left == ((void *)0)) + { + 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 == ((void *)0)) + { + 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 != ((void *)0)) + tm_impl_rebalance(_map_, unbalanced); + if (_map_->count == 0) + _map_->root = ((void *)0); + _map_->count--; + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->delete) + (_map_)->callbacks->delete (); + ; + return 1; +} +_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) +{ + if (tm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct treemap_node *scan = _map_->root; + while (scan->right != ((void *)0)) + 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 1; +} +_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) +{ + if (tm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct treemap_node *scan = _map_->root; + while (scan->left != ((void *)0)) + 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 1; +} +size_t tm_get(struct treemap *_map_, size_t key) +{ + if (tm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return (size_t){ 0 }; + } + struct treemap_node *node = tm_impl_get_node(_map_, key); + if (!node) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return (size_t){ 0 }; + } + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return node->value; +} +size_t *tm_get_ref(struct treemap *_map_, size_t key) +{ + if (tm_empty(_map_)) + { + _map_->flag = CMC_FLAG_EMPTY; + return ((void *)0); + } + struct treemap_node *node = tm_impl_get_node(_map_, key); + if (!node) + { + _map_->flag = CMC_FLAG_NOT_FOUND; + return ((void *)0); + } + _map_->flag = CMC_FLAG_OK; + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return &(node->value); +} +_Bool tm_contains(struct treemap *_map_, size_t key) +{ + _Bool result = tm_impl_get_node(_map_, key) != ((void *)0); + if ((_map_)->callbacks && (_map_)->callbacks->read) + (_map_)->callbacks->read(); + ; + return result; +} +_Bool tm_empty(struct treemap *_map_) +{ + return _map_->count == 0; +} +size_t tm_count(struct treemap *_map_) +{ + return _map_->count; +} +int tm_flag(struct treemap *_map_) +{ + return _map_->flag; +} +struct treemap *tm_copy_of(struct treemap *_map_) +{ + struct treemap *result = tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); + if (!result) + { + _map_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + struct treemap_node *root = _map_->root; + _Bool left_done = 0; + while (root) + { + if (!left_done) + { + while (root->left) + root = root->left; + } + size_t key; + size_t value; + if (_map_->f_key->cpy) + key = _map_->f_key->cpy(root->key); + else + key = root->key; + if (_map_->f_val->cpy) + value = _map_->f_val->cpy(root->value); + else + value = root->value; + tm_insert(result, key, value); + 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; + } + _map_->flag = CMC_FLAG_OK; + (result)->callbacks = _map_->callbacks; + return result; +} +_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) +{ + _map1_->flag = CMC_FLAG_OK; + _map2_->flag = CMC_FLAG_OK; + if (_map1_->count != _map2_->count) + return 0; + struct treemap_node *root = _map1_->root; + _Bool left_done = 0; + while (root) + { + if (!left_done) + { + while (root->left) + root = root->left; + } + struct treemap_node *node = tm_impl_get_node(_map2_, root->key); + if (node == ((void *)0)) + return 0; + if (_map1_->f_val->cmp(node->value, root->value) != 0) + 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; +} +static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value) +{ + struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); + if (!node) + return ((void *)0); + node->key = key; + node->value = value; + node->right = ((void *)0); + node->left = ((void *)0); + node->parent = ((void *)0); + node->height = 0; + return node; +} +static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key) +{ + struct treemap_node *scan = _map_->root; + while (scan != ((void *)0)) + { + if (_map_->f_key->cmp(scan->key, key) > 0) + scan = scan->left; + else if (_map_->f_key->cmp(scan->key, key) < 0) + scan = scan->right; + else + return scan; + } + return ((void *)0); +} +static unsigned char tm_impl_h(struct treemap_node *node) +{ + if (node == ((void *)0)) + return 0; + return node->height; +} +static unsigned char tm_impl_hupdate(struct treemap_node *node) +{ + if (node == ((void *)0)) + return 0; + unsigned char h_l = tm_impl_h(node->left); + unsigned char h_r = tm_impl_h(node->right); + return 1 + (h_l > h_r ? h_l : h_r); +} +static void tm_impl_rotate_right(struct treemap_node **Z) +{ + struct treemap_node *root = *Z; + struct treemap_node *new_root = root->left; + if (root->parent != ((void *)0)) + { + if (root->parent->left == root) + root->parent->left = new_root; + else + root->parent->right = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->left = new_root->right; + if (root->left) + root->left->parent = root; + new_root->right = root; + root->height = tm_impl_hupdate(root); + new_root->height = tm_impl_hupdate(new_root); + *Z = new_root; +} +static void tm_impl_rotate_left(struct treemap_node **Z) +{ + struct treemap_node *root = *Z; + struct treemap_node *new_root = root->right; + if (root->parent != ((void *)0)) + { + if (root->parent->right == root) + root->parent->right = new_root; + else + root->parent->left = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->right = new_root->left; + if (root->right) + root->right->parent = root; + new_root->left = root; + root->height = tm_impl_hupdate(root); + new_root->height = tm_impl_hupdate(new_root); + *Z = new_root; +} +static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node) +{ + struct treemap_node *scan = node, *child = ((void *)0); + int balance; + _Bool is_root = 0; + while (scan != ((void *)0)) + { + if (scan->parent == ((void *)0)) + is_root = 1; + scan->height = tm_impl_hupdate(scan); + balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); + if (balance >= 2) + { + child = scan->right; + if (tm_impl_h(child->right) < tm_impl_h(child->left)) + tm_impl_rotate_right(&(scan->right)); + tm_impl_rotate_left(&scan); + } + else if (balance <= -2) + { + child = scan->left; + if (tm_impl_h(child->left) < tm_impl_h(child->right)) + tm_impl_rotate_left(&(scan->left)); + tm_impl_rotate_right(&scan); + } + if (is_root) + { + _map_->root = scan; + is_root = 0; + } + scan = scan->parent; + } +} +struct treemap_iter tm_iter_start(struct treemap *target) +{ + struct treemap_iter iter; + iter.target = target; + iter.cursor = target->root; + iter.first = ((void *)0); + iter.last = ((void *)0); + iter.index = 0; + iter.start = 1; + iter.end = tm_empty(target); + if (!tm_empty(target)) + { + while (iter.cursor->left != ((void *)0)) + iter.cursor = iter.cursor->left; + iter.first = iter.cursor; + iter.last = target->root; + while (iter.last->right != ((void *)0)) + iter.last = iter.last->right; + } + return iter; +} +struct treemap_iter tm_iter_end(struct treemap *target) +{ + struct treemap_iter iter; + iter.target = target; + iter.cursor = target->root; + iter.first = ((void *)0); + iter.last = ((void *)0); + iter.index = 0; + iter.start = tm_empty(target); + iter.end = 1; + if (!tm_empty(target)) + { + while (iter.cursor->right != ((void *)0)) + iter.cursor = iter.cursor->right; + iter.last = iter.cursor; + iter.first = target->root; + while (iter.first->left != ((void *)0)) + iter.first = iter.first->left; + iter.index = target->count - 1; + } + return iter; +} +_Bool tm_iter_at_start(struct treemap_iter *iter) +{ + return tm_empty(iter->target) || iter->start; +} +_Bool tm_iter_at_end(struct treemap_iter *iter) +{ + return tm_empty(iter->target) || iter->end; +} +_Bool tm_iter_to_start(struct treemap_iter *iter) +{ + if (!tm_empty(iter->target)) + { + iter->index = 0; + iter->start = 1; + iter->end = tm_empty(iter->target); + iter->cursor = iter->first; + return 1; + } + return 0; +} +_Bool tm_iter_to_end(struct treemap_iter *iter) +{ + if (!tm_empty(iter->target)) + { + iter->index = iter->target->count - 1; + iter->start = tm_empty(iter->target); + iter->end = 1; + iter->cursor = iter->last; + return 1; + } + return 0; +} +_Bool tm_iter_next(struct treemap_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor == iter->last) + { + iter->end = 1; + return 0; + } + iter->start = tm_empty(iter->target); + if (iter->cursor->right != ((void *)0)) + { + iter->cursor = iter->cursor->right; + while (iter->cursor->left != ((void *)0)) + iter->cursor = iter->cursor->left; + iter->index++; + return 1; + } + while (1) + { + if (iter->cursor->parent->left == iter->cursor) + { + iter->cursor = iter->cursor->parent; + iter->index++; + return 1; + } + iter->cursor = iter->cursor->parent; + } +} +_Bool tm_iter_prev(struct treemap_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor == iter->first) + { + iter->start = 1; + return 0; + } + iter->end = tm_empty(iter->target); + if (iter->cursor->left != ((void *)0)) + { + iter->cursor = iter->cursor->left; + while (iter->cursor->right != ((void *)0)) + iter->cursor = iter->cursor->right; + iter->index--; + return 1; + } + while (1) + { + if (iter->cursor->parent->right == iter->cursor) + { + iter->cursor = iter->cursor->parent; + iter->index--; + return 1; + } + iter->cursor = iter->cursor->parent; + } +} +_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor == iter->last) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + for (size_t i = 0; i < steps; i++) + tm_iter_next(iter); + return 1; +} +_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor == iter->first) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + for (size_t i = 0; i < steps; i++) + tm_iter_prev(iter); + return 1; +} +_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return tm_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return tm_iter_advance(iter, index - iter->index); + return 1; +} +size_t tm_iter_key(struct treemap_iter *iter) +{ + if (tm_empty(iter->target)) + return (size_t){ 0 }; + return iter->cursor->key; +} +size_t tm_iter_value(struct treemap_iter *iter) +{ + if (tm_empty(iter->target)) + return (size_t){ 0 }; + return iter->cursor->value; +} +size_t *tm_iter_rvalue(struct treemap_iter *iter) +{ + if (tm_empty(iter->target)) + return ((void *)0); + return &(iter->cursor->value); +} +size_t tm_iter_index(struct treemap_iter *iter) +{ + return iter->index; +} +_Bool tm_to_string(struct treemap *_map_, FILE *fptr) +{ + struct treemap *m_ = _map_; + return 0 <= fprintf(fptr, + "struct %s<%s, %s> " + "at %p { " + "root:%p, " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "f_key:%p, " + "alloc:%p, " + "callbacks:%p }", + "treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, + m_->alloc, (m_)->callbacks); +} +_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, + const char *key_val_sep) +{ + fprintf(fptr, "%s", start); + struct treemap_node *root = _map_->root; + _Bool left_done = 0; + size_t i = 0; + while (root) + { + if (!left_done) + { + while (root->left) + root = root->left; + } + if (!_map_->f_key->str(fptr, root->key)) + return 0; + fprintf(fptr, "%s", key_val_sep); + if (!_map_->f_val->str(fptr, root->value)) + return 0; + if (++i < _map_->count) + fprintf(fptr, "%s", separator); + left_done = 1; + if (root->right) + { + left_done = 0; + root = root->right; + } + else if (root->parent) + { + while (root->parent && root == root->parent->right) + root = root->parent; + if (!root->parent) + break; + root = root->parent; + } + else + break; + } + fprintf(fptr, "%s", end); + return 1; +} diff --git a/tests/src/tst_cmc_treeset.c b/tests/src/tst_cmc_treeset.c index 1b46b22..b0a60ce 100644 --- a/tests/src/tst_cmc_treeset.c +++ b/tests/src/tst_cmc_treeset.c @@ -1,7 +1,841 @@ - #include "tst_cmc_treeset.h" +#include "tst_cmc_treeset.h" - - 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); static void ts_impl_rotate_left(struct treeset_node * *Z); static void ts_impl_rebalance(struct treeset * _set_, struct treeset_node * node); struct treeset *ts_new(struct treeset_fval * f_val) { return ts_new_custom(f_val, ((void *)0), ((void *)0)); } struct treeset *ts_new_custom(struct treeset_fval * f_val, struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) { ; if (!f_val) return ((void *)0); if (!alloc) alloc = &cmc_alloc_node_default; struct treeset *_set_ = alloc->malloc(sizeof(struct treeset)); if (!_set_) return ((void *)0); _set_->count = 0; _set_->root = ((void *)0); _set_->flag = CMC_FLAG_OK; _set_->f_val = f_val; _set_->alloc = alloc; (_set_)->callbacks = callbacks; return _set_; } void ts_clear(struct treeset * _set_) { struct treeset_node *scan = _set_->root; struct treeset_node *up = ((void *)0); while (scan != ((void *)0)) { if (scan->left != ((void *)0)) { struct treeset_node *left = scan->left; scan->left = up; up = scan; scan = left; } else if (scan->right != ((void *)0)) { struct treeset_node *right = scan->right; scan->left = up; scan->right = ((void *)0); up = scan; scan = right; } else { if (up == ((void *)0)) { if (_set_->f_val->free) _set_->f_val->free(scan->value); _set_->alloc->free(scan); scan = ((void *)0); } while (up != ((void *)0)) { if (_set_->f_val->free) _set_->f_val->free(scan->value); _set_->alloc->free(scan); if (up->right != ((void *)0)) { scan = up->right; up->right = ((void *)0); break; } else { scan = up; up = up->left; } } } } _set_->count = 0; _set_->root = ((void *)0); _set_->flag = CMC_FLAG_OK; } 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) { ; if (!alloc) _set_->alloc = &cmc_alloc_node_default; else _set_->alloc = alloc; (_set_)->callbacks = callbacks; _set_->flag = CMC_FLAG_OK; } _Bool ts_insert(struct treeset * _set_, size_t value) { if (ts_empty(_set_)) { _set_->root = ts_impl_new_node(_set_, value); if (!_set_->root) { _set_->flag = CMC_FLAG_ALLOC; return 0; } } else { struct treeset_node *scan = _set_->root; struct treeset_node *parent = scan; while (scan != ((void *)0)) { 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 0; } } struct treeset_node * node; if (_set_->f_val->cmp(parent->value, value) > 0) { parent->left = ts_impl_new_node(_set_, value); if (!parent->left) { _set_->flag = CMC_FLAG_ALLOC; return 0; } parent->left->parent = parent; node = parent->left; } else { parent->right = ts_impl_new_node(_set_, value); if (!parent->right) { _set_->flag = CMC_FLAG_ALLOC; return 0; } parent->right->parent = parent; node = parent->right; } ts_impl_rebalance(_set_, node); } _set_->count++; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->create) (_set_)->callbacks->create();; return 1; } _Bool ts_remove(struct treeset * _set_, size_t value) { if (ts_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *node = ts_impl_get_node(_set_, value); if (!node) { _set_->flag = CMC_FLAG_NOT_FOUND; return 0; } struct treeset_node *temp = ((void *)0), *unbalanced = ((void *)0); _Bool is_root = node->parent == ((void *)0); if (node->left == ((void *)0) && node->right == ((void *)0)) { if (is_root) _set_->root = ((void *)0); else { unbalanced = node->parent; if (node->parent->right == node) node->parent->right = ((void *)0); else node->parent->left = ((void *)0); } _set_->alloc->free(node); } else if (node->left == ((void *)0)) { if (is_root) { _set_->root = node->right; _set_->root->parent = ((void *)0); } 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 == ((void *)0)) { if (is_root) { _set_->root = node->left; _set_->root->parent = ((void *)0); } 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 != ((void *)0)) temp = temp->left; size_t temp_value = temp->value; unbalanced = temp->parent; if (temp->left == ((void *)0) && temp->right == ((void *)0)) { if (temp->parent->right == temp) temp->parent->right = ((void *)0); else temp->parent->left = ((void *)0); } else if (temp->left == ((void *)0)) { 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 == ((void *)0)) { 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 != ((void *)0)) ts_impl_rebalance(_set_, unbalanced); if (_set_->count == 0) _set_->root = ((void *)0); _set_->count--; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->delete) (_set_)->callbacks->delete();; return 1; } _Bool ts_max(struct treeset * _set_, size_t * value) { if (ts_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *scan = _set_->root; while (scan->right != ((void *)0)) scan = scan->right; if (value) *value = scan->value; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool ts_min(struct treeset * _set_, size_t * value) { if (ts_empty(_set_)) { _set_->flag = CMC_FLAG_EMPTY; return 0; } struct treeset_node *scan = _set_->root; while (scan->left != ((void *)0)) scan = scan->left; if (value) *value = scan->value; _set_->flag = CMC_FLAG_OK; if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return 1; } _Bool ts_contains(struct treeset * _set_, size_t value) { _Bool result = ts_impl_get_node(_set_, value) != ((void *)0); if ((_set_)->callbacks && (_set_)->callbacks->read) (_set_)->callbacks->read();; return result; } _Bool ts_empty(struct treeset * _set_) { return _set_->count == 0; } size_t ts_count(struct treeset * _set_) { return _set_->count; } int ts_flag(struct treeset * _set_) { return _set_->flag; } struct treeset *ts_copy_of(struct treeset * _set_) { struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0)); if (!result) { _set_->flag = CMC_FLAG_ERROR; return ((void *)0); } (result)->callbacks = _set_->callbacks; if (!ts_empty(_set_)) { struct treeset_iter iter = ts_iter_start(_set_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { if (_set_->f_val->cpy) ts_insert (result, _set_->f_val->cpy(ts_iter_value(&iter))); else ts_insert(result, ts_iter_value(&iter)); } } _set_->flag = CMC_FLAG_OK; return result; } _Bool ts_equals(struct treeset * _set1_, struct treeset * _set2_) { _set1_->flag = CMC_FLAG_OK; _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { if (ts_impl_get_node(_set2_, ts_iter_value(&iter)) == ((void *)0)) return 0; } return 1; } 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)); if (!node) return ((void *)0); node->value = value; node->right = ((void *)0); node->left = ((void *)0); node->parent = ((void *)0); node->height = 0; return node; } static struct treeset_node * ts_impl_get_node(struct treeset * _set_, size_t value) { struct treeset_node *scan = _set_->root; while (scan != ((void *)0)) { 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 ((void *)0); } static unsigned char ts_impl_h(struct treeset_node * node) { if (node == ((void *)0)) return 0; return node->height; } static unsigned char ts_impl_hupdate(struct treeset_node * node) { if (node == ((void *)0)) return 0; unsigned char h_l = ts_impl_h(node->left); unsigned char h_r = ts_impl_h(node->right); return 1 + (h_l > h_r ? h_l : h_r); } static void ts_impl_rotate_right(struct treeset_node * *Z) { struct treeset_node *root = *Z; struct treeset_node *new_root = root->left; if (root->parent != ((void *)0)) { if (root->parent->left == root) root->parent->left = new_root; else root->parent->right = new_root; } new_root->parent = root->parent; root->parent = new_root; root->left = new_root->right; if (root->left) root->left->parent = root; new_root->right = root; root->height = ts_impl_hupdate(root); new_root->height = ts_impl_hupdate(new_root); *Z = new_root; } static void ts_impl_rotate_left(struct treeset_node * *Z) { struct treeset_node *root = *Z; struct treeset_node *new_root = root->right; if (root->parent != ((void *)0)) { if (root->parent->right == root) root->parent->right = new_root; else root->parent->left = new_root; } new_root->parent = root->parent; root->parent = new_root; root->right = new_root->left; if (root->right) root->right->parent = root; new_root->left = root; root->height = ts_impl_hupdate(root); new_root->height = ts_impl_hupdate(new_root); *Z = new_root; } static void ts_impl_rebalance(struct treeset * _set_, struct treeset_node * node) { struct treeset_node *scan = node, *child = ((void *)0); int balance; _Bool is_root = 0; while (scan != ((void *)0)) { if (scan->parent == ((void *)0)) is_root = 1; scan->height = ts_impl_hupdate(scan); balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); if (balance >= 2) { child = scan->right; if (ts_impl_h(child->right) < ts_impl_h(child->left)) ts_impl_rotate_right(&(scan->right)); ts_impl_rotate_left(&scan); } else if (balance <= -2) { child = scan->left; if (ts_impl_h(child->left) < ts_impl_h(child->right)) ts_impl_rotate_left(&(scan->left)); ts_impl_rotate_right(&scan); } if (is_root) { _set_->root = scan; is_root = 0; } scan = scan->parent; } } struct treeset_iter ts_iter_start(struct treeset * target) { struct treeset_iter iter; iter.target = target; iter.cursor = target->root; iter.first = ((void *)0); iter.last = ((void *)0); iter.index = 0; iter.start = 1; iter.end = ts_empty(target); if (!ts_empty(target)) { while (iter.cursor->left != ((void *)0)) iter.cursor = iter.cursor->left; iter.first = iter.cursor; iter.last = target->root; while (iter.last->right != ((void *)0)) iter.last = iter.last->right; } return iter; } struct treeset_iter ts_iter_end(struct treeset * target) { struct treeset_iter iter; iter.target = target; iter.cursor = target->root; iter.first = ((void *)0); iter.last = ((void *)0); iter.index = 0; iter.start = ts_empty(target); iter.end = 1; if (!ts_empty(target)) { while (iter.cursor->right != ((void *)0)) iter.cursor = iter.cursor->right; iter.last = iter.cursor; iter.first = target->root; while (iter.first->left != ((void *)0)) iter.first = iter.first->left; iter.index = target->count - 1; } return iter; } _Bool ts_iter_at_start(struct treeset_iter * iter) { return ts_empty(iter->target) || iter->start; } _Bool ts_iter_at_end(struct treeset_iter * iter) { return ts_empty(iter->target) || iter->end; } _Bool ts_iter_to_start(struct treeset_iter * iter) { if (!ts_empty(iter->target)) { iter->index = 0; iter->start = 1; iter->end = ts_empty(iter->target); iter->cursor = iter->first; return 1; } return 0; } _Bool ts_iter_to_end(struct treeset_iter * iter) { if (!ts_empty(iter->target)) { iter->index = iter->target->count - 1; iter->start = ts_empty(iter->target); iter->end = 1; iter->cursor = iter->last; return 1; } return 0; } _Bool ts_iter_next(struct treeset_iter * iter) { if (iter->end) return 0; if (iter->cursor == iter->last) { iter->end = 1; return 0; } iter->start = ts_empty(iter->target); if (iter->cursor->right != ((void *)0)) { iter->cursor = iter->cursor->right; while (iter->cursor->left != ((void *)0)) iter->cursor = iter->cursor->left; iter->index++; return 1; } while (1) { if (iter->cursor->parent->left == iter->cursor) { iter->cursor = iter->cursor->parent; iter->index++; return 1; } iter->cursor = iter->cursor->parent; } } _Bool ts_iter_prev(struct treeset_iter * iter) { if (iter->start) return 0; if (iter->cursor == iter->first) { iter->start = 1; return 0; } iter->end = ts_empty(iter->target); if (iter->cursor->left != ((void *)0)) { iter->cursor = iter->cursor->left; while (iter->cursor->right != ((void *)0)) iter->cursor = iter->cursor->right; iter->index--; return 1; } while (1) { if (iter->cursor->parent->right == iter->cursor) { iter->cursor = iter->cursor->parent; iter->index--; return 1; } iter->cursor = iter->cursor->parent; } } _Bool ts_iter_advance(struct treeset_iter * iter, size_t steps) { if (iter->end) return 0; if (iter->cursor == iter->last) { iter->end = 1; return 0; } if (steps == 0 || iter->index + steps >= iter->target->count) return 0; for (size_t i = 0; i < steps; i++) ts_iter_next(iter); return 1; } _Bool ts_iter_rewind(struct treeset_iter * iter, size_t steps) { if (iter->start) return 0; if (iter->cursor == iter->first) { iter->start = 1; return 0; } if (steps == 0 || iter->index < steps) return 0; for (size_t i = 0; i < steps; i++) ts_iter_prev(iter); return 1; } _Bool ts_iter_go_to(struct treeset_iter * iter, size_t index) { if (index >= iter->target->count) return 0; if (iter->index > index) return ts_iter_rewind(iter, iter->index - index); else if (iter->index < index) return ts_iter_advance(iter, index - iter->index); return 1; } size_t ts_iter_value(struct treeset_iter * iter) { if (ts_empty(iter->target)) return (size_t){ 0 }; return iter->cursor->value; } size_t ts_iter_index(struct treeset_iter * iter) { return iter->index; } struct treeset *ts_union(struct treeset * _set1_, struct treeset * _set2_) { struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); struct treeset_iter iter2 = ts_iter_start(_set2_); for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) { ts_insert(_set_r_, ts_iter_value(&iter1)); } for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) { ts_insert(_set_r_, ts_iter_value(&iter2)); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_intersection(struct treeset * _set1_, struct treeset * _set2_) { struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; struct treeset_iter iter = ts_iter_start(_set_A_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set_B_, value) != ((void *)0)) ts_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_difference(struct treeset * _set1_, struct treeset * _set2_) { struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set2_, value) == ((void *)0)) ts_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } struct treeset *ts_symmetric_difference(struct treeset * _set1_, struct treeset * _set2_) { struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); if (!_set_r_) return ((void *)0); struct treeset_iter iter1 = ts_iter_start(_set1_); struct treeset_iter iter2 = ts_iter_start(_set2_); for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) { size_t value = ts_iter_value(&iter1); if (ts_impl_get_node(_set2_, value) == ((void *)0)) ts_insert(_set_r_, value); } for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) { size_t value = ts_iter_value(&iter2); if (ts_impl_get_node(_set1_, value) == ((void *)0)) ts_insert(_set_r_, value); } (_set_r_)->callbacks = _set1_->callbacks; return _set_r_; } _Bool ts_is_subset(struct treeset * _set1_, struct treeset * _set2_) { if (_set1_->count > _set2_->count) return 0; if (ts_empty(_set1_)) return 1; struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set2_, value) == ((void *)0)) return 0; } return 1; } _Bool ts_is_superset(struct treeset * _set1_, struct treeset * _set2_) { return ts_is_subset(_set2_, _set1_); } _Bool ts_is_proper_subset(struct treeset * _set1_, struct treeset * _set2_) { if (_set1_->count >= _set2_->count) return 0; if (ts_empty(_set1_)) { if (!ts_empty(_set2_)) return 1; else return 0; } struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set2_, value) == ((void *)0)) return 0; } return 1; } _Bool ts_is_proper_superset(struct treeset * _set1_, struct treeset * _set2_) { return ts_is_proper_subset(_set2_, _set1_); } _Bool ts_is_disjointset(struct treeset * _set1_, struct treeset * _set2_) { if (ts_empty(_set1_)) return 1; struct treeset_iter iter = ts_iter_start(_set1_); for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) { size_t value = ts_iter_value(&iter); if (ts_impl_get_node(_set2_, value) != ((void *)0)) return 0; } return 1; } _Bool ts_to_string(struct treeset * _set_, FILE * fptr) { struct treeset *s_ = _set_; return 0 <= fprintf(fptr, "struct %s<%s> " "at %p { " "root:%p, " "count:%" "I64u" ", " "flag:%d, " "f_val:%p, " "alloc:%p, " "callbacks:%p }", "treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); } _Bool ts_print(struct treeset * _set_, FILE * fptr, const char *start, const char *separator, const char *end) { fprintf(fptr, "%s", start); struct treeset_node *root = _set_->root; _Bool left_done = 0; size_t i = 0; while (root) { if (!left_done) { while (root->left) root = root->left; } if (!_set_->f_val->str(fptr, root->value)) return 0; if (++i < _set_->count) fprintf(fptr, "%s", separator); left_done = 1; if (root->right) { left_done = 0; root = root->right; } else if (root->parent) { while (root->parent && root == root->parent->right) root = root->parent; if (!root->parent) break; root = root->parent; } else break; } fprintf(fptr, "%s", end); return 1; } - - \ No newline at end of file +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); +static void ts_impl_rotate_left(struct treeset_node **Z); +static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node); +struct treeset *ts_new(struct treeset_fval *f_val) +{ + return ts_new_custom(f_val, ((void *)0), ((void *)0)); +} +struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) +{ + ; + if (!f_val) + return ((void *)0); + if (!alloc) + alloc = &cmc_alloc_node_default; + struct treeset *_set_ = alloc->malloc(sizeof(struct treeset)); + if (!_set_) + return ((void *)0); + _set_->count = 0; + _set_->root = ((void *)0); + _set_->flag = CMC_FLAG_OK; + _set_->f_val = f_val; + _set_->alloc = alloc; + (_set_)->callbacks = callbacks; + return _set_; +} +void ts_clear(struct treeset *_set_) +{ + struct treeset_node *scan = _set_->root; + struct treeset_node *up = ((void *)0); + while (scan != ((void *)0)) + { + if (scan->left != ((void *)0)) + { + struct treeset_node *left = scan->left; + scan->left = up; + up = scan; + scan = left; + } + else if (scan->right != ((void *)0)) + { + struct treeset_node *right = scan->right; + scan->left = up; + scan->right = ((void *)0); + up = scan; + scan = right; + } + else + { + if (up == ((void *)0)) + { + if (_set_->f_val->free) + _set_->f_val->free(scan->value); + _set_->alloc->free(scan); + scan = ((void *)0); + } + while (up != ((void *)0)) + { + if (_set_->f_val->free) + _set_->f_val->free(scan->value); + _set_->alloc->free(scan); + if (up->right != ((void *)0)) + { + scan = up->right; + up->right = ((void *)0); + break; + } + else + { + scan = up; + up = up->left; + } + } + } + } + _set_->count = 0; + _set_->root = ((void *)0); + _set_->flag = CMC_FLAG_OK; +} +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) +{ + ; + if (!alloc) + _set_->alloc = &cmc_alloc_node_default; + else + _set_->alloc = alloc; + (_set_)->callbacks = callbacks; + _set_->flag = CMC_FLAG_OK; +} +_Bool ts_insert(struct treeset *_set_, size_t value) +{ + if (ts_empty(_set_)) + { + _set_->root = ts_impl_new_node(_set_, value); + if (!_set_->root) + { + _set_->flag = CMC_FLAG_ALLOC; + return 0; + } + } + else + { + struct treeset_node *scan = _set_->root; + struct treeset_node *parent = scan; + while (scan != ((void *)0)) + { + 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 0; + } + } + struct treeset_node *node; + if (_set_->f_val->cmp(parent->value, value) > 0) + { + parent->left = ts_impl_new_node(_set_, value); + if (!parent->left) + { + _set_->flag = CMC_FLAG_ALLOC; + return 0; + } + parent->left->parent = parent; + node = parent->left; + } + else + { + parent->right = ts_impl_new_node(_set_, value); + if (!parent->right) + { + _set_->flag = CMC_FLAG_ALLOC; + return 0; + } + parent->right->parent = parent; + node = parent->right; + } + ts_impl_rebalance(_set_, node); + } + _set_->count++; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->create) + (_set_)->callbacks->create(); + ; + return 1; +} +_Bool ts_remove(struct treeset *_set_, size_t value) +{ + if (ts_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct treeset_node *node = ts_impl_get_node(_set_, value); + if (!node) + { + _set_->flag = CMC_FLAG_NOT_FOUND; + return 0; + } + struct treeset_node *temp = ((void *)0), *unbalanced = ((void *)0); + _Bool is_root = node->parent == ((void *)0); + if (node->left == ((void *)0) && node->right == ((void *)0)) + { + if (is_root) + _set_->root = ((void *)0); + else + { + unbalanced = node->parent; + if (node->parent->right == node) + node->parent->right = ((void *)0); + else + node->parent->left = ((void *)0); + } + _set_->alloc->free(node); + } + else if (node->left == ((void *)0)) + { + if (is_root) + { + _set_->root = node->right; + _set_->root->parent = ((void *)0); + } + 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 == ((void *)0)) + { + if (is_root) + { + _set_->root = node->left; + _set_->root->parent = ((void *)0); + } + 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 != ((void *)0)) + temp = temp->left; + size_t temp_value = temp->value; + unbalanced = temp->parent; + if (temp->left == ((void *)0) && temp->right == ((void *)0)) + { + if (temp->parent->right == temp) + temp->parent->right = ((void *)0); + else + temp->parent->left = ((void *)0); + } + else if (temp->left == ((void *)0)) + { + 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 == ((void *)0)) + { + 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 != ((void *)0)) + ts_impl_rebalance(_set_, unbalanced); + if (_set_->count == 0) + _set_->root = ((void *)0); + _set_->count--; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->delete) + (_set_)->callbacks->delete (); + ; + return 1; +} +_Bool ts_max(struct treeset *_set_, size_t *value) +{ + if (ts_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct treeset_node *scan = _set_->root; + while (scan->right != ((void *)0)) + scan = scan->right; + if (value) + *value = scan->value; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return 1; +} +_Bool ts_min(struct treeset *_set_, size_t *value) +{ + if (ts_empty(_set_)) + { + _set_->flag = CMC_FLAG_EMPTY; + return 0; + } + struct treeset_node *scan = _set_->root; + while (scan->left != ((void *)0)) + scan = scan->left; + if (value) + *value = scan->value; + _set_->flag = CMC_FLAG_OK; + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return 1; +} +_Bool ts_contains(struct treeset *_set_, size_t value) +{ + _Bool result = ts_impl_get_node(_set_, value) != ((void *)0); + if ((_set_)->callbacks && (_set_)->callbacks->read) + (_set_)->callbacks->read(); + ; + return result; +} +_Bool ts_empty(struct treeset *_set_) +{ + return _set_->count == 0; +} +size_t ts_count(struct treeset *_set_) +{ + return _set_->count; +} +int ts_flag(struct treeset *_set_) +{ + return _set_->flag; +} +struct treeset *ts_copy_of(struct treeset *_set_) +{ + struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0)); + if (!result) + { + _set_->flag = CMC_FLAG_ERROR; + return ((void *)0); + } + (result)->callbacks = _set_->callbacks; + if (!ts_empty(_set_)) + { + struct treeset_iter iter = ts_iter_start(_set_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + if (_set_->f_val->cpy) + ts_insert(result, _set_->f_val->cpy(ts_iter_value(&iter))); + else + ts_insert(result, ts_iter_value(&iter)); + } + } + _set_->flag = CMC_FLAG_OK; + return result; +} +_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) +{ + _set1_->flag = CMC_FLAG_OK; + _set2_->flag = CMC_FLAG_OK; + if (_set1_->count != _set2_->count) + return 0; + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + if (ts_impl_get_node(_set2_, ts_iter_value(&iter)) == ((void *)0)) + return 0; + } + return 1; +} +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)); + if (!node) + return ((void *)0); + node->value = value; + node->right = ((void *)0); + node->left = ((void *)0); + node->parent = ((void *)0); + node->height = 0; + return node; +} +static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value) +{ + struct treeset_node *scan = _set_->root; + while (scan != ((void *)0)) + { + 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 ((void *)0); +} +static unsigned char ts_impl_h(struct treeset_node *node) +{ + if (node == ((void *)0)) + return 0; + return node->height; +} +static unsigned char ts_impl_hupdate(struct treeset_node *node) +{ + if (node == ((void *)0)) + return 0; + unsigned char h_l = ts_impl_h(node->left); + unsigned char h_r = ts_impl_h(node->right); + return 1 + (h_l > h_r ? h_l : h_r); +} +static void ts_impl_rotate_right(struct treeset_node **Z) +{ + struct treeset_node *root = *Z; + struct treeset_node *new_root = root->left; + if (root->parent != ((void *)0)) + { + if (root->parent->left == root) + root->parent->left = new_root; + else + root->parent->right = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->left = new_root->right; + if (root->left) + root->left->parent = root; + new_root->right = root; + root->height = ts_impl_hupdate(root); + new_root->height = ts_impl_hupdate(new_root); + *Z = new_root; +} +static void ts_impl_rotate_left(struct treeset_node **Z) +{ + struct treeset_node *root = *Z; + struct treeset_node *new_root = root->right; + if (root->parent != ((void *)0)) + { + if (root->parent->right == root) + root->parent->right = new_root; + else + root->parent->left = new_root; + } + new_root->parent = root->parent; + root->parent = new_root; + root->right = new_root->left; + if (root->right) + root->right->parent = root; + new_root->left = root; + root->height = ts_impl_hupdate(root); + new_root->height = ts_impl_hupdate(new_root); + *Z = new_root; +} +static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) +{ + struct treeset_node *scan = node, *child = ((void *)0); + int balance; + _Bool is_root = 0; + while (scan != ((void *)0)) + { + if (scan->parent == ((void *)0)) + is_root = 1; + scan->height = ts_impl_hupdate(scan); + balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); + if (balance >= 2) + { + child = scan->right; + if (ts_impl_h(child->right) < ts_impl_h(child->left)) + ts_impl_rotate_right(&(scan->right)); + ts_impl_rotate_left(&scan); + } + else if (balance <= -2) + { + child = scan->left; + if (ts_impl_h(child->left) < ts_impl_h(child->right)) + ts_impl_rotate_left(&(scan->left)); + ts_impl_rotate_right(&scan); + } + if (is_root) + { + _set_->root = scan; + is_root = 0; + } + scan = scan->parent; + } +} +struct treeset_iter ts_iter_start(struct treeset *target) +{ + struct treeset_iter iter; + iter.target = target; + iter.cursor = target->root; + iter.first = ((void *)0); + iter.last = ((void *)0); + iter.index = 0; + iter.start = 1; + iter.end = ts_empty(target); + if (!ts_empty(target)) + { + while (iter.cursor->left != ((void *)0)) + iter.cursor = iter.cursor->left; + iter.first = iter.cursor; + iter.last = target->root; + while (iter.last->right != ((void *)0)) + iter.last = iter.last->right; + } + return iter; +} +struct treeset_iter ts_iter_end(struct treeset *target) +{ + struct treeset_iter iter; + iter.target = target; + iter.cursor = target->root; + iter.first = ((void *)0); + iter.last = ((void *)0); + iter.index = 0; + iter.start = ts_empty(target); + iter.end = 1; + if (!ts_empty(target)) + { + while (iter.cursor->right != ((void *)0)) + iter.cursor = iter.cursor->right; + iter.last = iter.cursor; + iter.first = target->root; + while (iter.first->left != ((void *)0)) + iter.first = iter.first->left; + iter.index = target->count - 1; + } + return iter; +} +_Bool ts_iter_at_start(struct treeset_iter *iter) +{ + return ts_empty(iter->target) || iter->start; +} +_Bool ts_iter_at_end(struct treeset_iter *iter) +{ + return ts_empty(iter->target) || iter->end; +} +_Bool ts_iter_to_start(struct treeset_iter *iter) +{ + if (!ts_empty(iter->target)) + { + iter->index = 0; + iter->start = 1; + iter->end = ts_empty(iter->target); + iter->cursor = iter->first; + return 1; + } + return 0; +} +_Bool ts_iter_to_end(struct treeset_iter *iter) +{ + if (!ts_empty(iter->target)) + { + iter->index = iter->target->count - 1; + iter->start = ts_empty(iter->target); + iter->end = 1; + iter->cursor = iter->last; + return 1; + } + return 0; +} +_Bool ts_iter_next(struct treeset_iter *iter) +{ + if (iter->end) + return 0; + if (iter->cursor == iter->last) + { + iter->end = 1; + return 0; + } + iter->start = ts_empty(iter->target); + if (iter->cursor->right != ((void *)0)) + { + iter->cursor = iter->cursor->right; + while (iter->cursor->left != ((void *)0)) + iter->cursor = iter->cursor->left; + iter->index++; + return 1; + } + while (1) + { + if (iter->cursor->parent->left == iter->cursor) + { + iter->cursor = iter->cursor->parent; + iter->index++; + return 1; + } + iter->cursor = iter->cursor->parent; + } +} +_Bool ts_iter_prev(struct treeset_iter *iter) +{ + if (iter->start) + return 0; + if (iter->cursor == iter->first) + { + iter->start = 1; + return 0; + } + iter->end = ts_empty(iter->target); + if (iter->cursor->left != ((void *)0)) + { + iter->cursor = iter->cursor->left; + while (iter->cursor->right != ((void *)0)) + iter->cursor = iter->cursor->right; + iter->index--; + return 1; + } + while (1) + { + if (iter->cursor->parent->right == iter->cursor) + { + iter->cursor = iter->cursor->parent; + iter->index--; + return 1; + } + iter->cursor = iter->cursor->parent; + } +} +_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps) +{ + if (iter->end) + return 0; + if (iter->cursor == iter->last) + { + iter->end = 1; + return 0; + } + if (steps == 0 || iter->index + steps >= iter->target->count) + return 0; + for (size_t i = 0; i < steps; i++) + ts_iter_next(iter); + return 1; +} +_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps) +{ + if (iter->start) + return 0; + if (iter->cursor == iter->first) + { + iter->start = 1; + return 0; + } + if (steps == 0 || iter->index < steps) + return 0; + for (size_t i = 0; i < steps; i++) + ts_iter_prev(iter); + return 1; +} +_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index) +{ + if (index >= iter->target->count) + return 0; + if (iter->index > index) + return ts_iter_rewind(iter, iter->index - index); + else if (iter->index < index) + return ts_iter_advance(iter, index - iter->index); + return 1; +} +size_t ts_iter_value(struct treeset_iter *iter) +{ + if (ts_empty(iter->target)) + return (size_t){ 0 }; + return iter->cursor->value; +} +size_t ts_iter_index(struct treeset_iter *iter) +{ + return iter->index; +} +struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) +{ + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset_iter iter1 = ts_iter_start(_set1_); + struct treeset_iter iter2 = ts_iter_start(_set2_); + for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) + { + ts_insert(_set_r_, ts_iter_value(&iter1)); + } + for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) + { + ts_insert(_set_r_, ts_iter_value(&iter2)); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) +{ + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; + struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; + struct treeset_iter iter = ts_iter_start(_set_A_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set_B_, value) != ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) +{ + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) +{ + struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); + if (!_set_r_) + return ((void *)0); + struct treeset_iter iter1 = ts_iter_start(_set1_); + struct treeset_iter iter2 = ts_iter_start(_set2_); + for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) + { + size_t value = ts_iter_value(&iter1); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) + { + size_t value = ts_iter_value(&iter2); + if (ts_impl_get_node(_set1_, value) == ((void *)0)) + ts_insert(_set_r_, value); + } + (_set_r_)->callbacks = _set1_->callbacks; + return _set_r_; +} +_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (_set1_->count > _set2_->count) + return 0; + if (ts_empty(_set1_)) + return 1; + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + return 0; + } + return 1; +} +_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_) +{ + return ts_is_subset(_set2_, _set1_); +} +_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (_set1_->count >= _set2_->count) + return 0; + if (ts_empty(_set1_)) + { + if (!ts_empty(_set2_)) + return 1; + else + return 0; + } + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) == ((void *)0)) + return 0; + } + return 1; +} +_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_) +{ + return ts_is_proper_subset(_set2_, _set1_); +} +_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_) +{ + if (ts_empty(_set1_)) + return 1; + struct treeset_iter iter = ts_iter_start(_set1_); + for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) + { + size_t value = ts_iter_value(&iter); + if (ts_impl_get_node(_set2_, value) != ((void *)0)) + return 0; + } + return 1; +} +_Bool ts_to_string(struct treeset *_set_, FILE *fptr) +{ + struct treeset *s_ = _set_; + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "root:%p, " + "count:%" + "I64u" + ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + "treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); +} +_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + struct treeset_node *root = _set_->root; + _Bool left_done = 0; + size_t i = 0; + while (root) + { + if (!left_done) + { + while (root->left) + root = root->left; + } + if (!_set_->f_val->str(fptr, root->value)) + return 0; + if (++i < _set_->count) + fprintf(fptr, "%s", separator); + left_done = 1; + if (root->right) + { + left_done = 0; + root = root->right; + } + else if (root->parent) + { + while (root->parent && root == root->parent->right) + root = root->parent; + if (!root->parent) + break; + root = root->parent; + } + else + break; + } + fprintf(fptr, "%s", end); + return 1; +} From 1911415879af18b93176682670eefa1008739c54 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Mon, 28 Sep 2020 20:41:54 -0300 Subject: [PATCH 13/20] Adding unused to cmc_alloc_node_default --- src/cor_alloc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cor_alloc.h b/src/cor_alloc.h index 22dac63..d27cd98 100644 --- a/src/cor_alloc.h +++ b/src/cor_alloc.h @@ -17,7 +17,7 @@ #define CMC_ALLOC_NODE_NAME cmc_alloc_node #endif -#include +#include "cor_core.h" /** * struct cmc_alloc_node @@ -32,6 +32,6 @@ static struct CMC_ALLOC_NODE_NAME void *(*calloc)(size_t, size_t); void *(*realloc)(void *, size_t); void (*free)(void *); -} cmc_alloc_node_default = { malloc, calloc, realloc, free }; +} CMC_UNUSED cmc_alloc_node_default = { malloc, calloc, realloc, free }; #endif /* CMC_COR_ALLOC_H */ From 4e194f28eef641a56a1f558c7e6187e1b9ad3f1b Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 29 Sep 2020 17:08:40 -0300 Subject: [PATCH 14/20] WIP new architecture, tests will fail --- README.md | 12 +--- examples/example.c | 2 +- src/ext_cmc_bitset.h | 12 ++-- src/ext_cmc_deque.h | 55 +++++++++++----- src/macro_collections.h | 141 +++++++++++++++++++++++----------------- 5 files changed, 131 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index cc0f98b..9d689ff 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Below is a minimal example that makes use of some core functionalities. And a lo // needs to be generated first. Then, we can add other parts after. This macro // does all of that for us. The STR part will provide us with a function that // will be used later. -C_MACRO_COLLECTIONS_GEN(CMC, LIST, MY_LIST_PARAMS, (STR)) +C_MACRO_COLLECTIONS_EXTENDED(CMC, LIST, MY_LIST_PARAMS, (STR)) int main(void) { @@ -138,11 +138,12 @@ The C Macro Collections library is organized into many other sub-libraries. The Every macro that generates code for a certain collection can be found with the following template. Some exceptions exist as certain collections don't have or can't have some features. One big example is the `UTL` library, which does not follow this pattern. ``` -macro_name := CMC_[ lib ]_[ collection ]_[ part ]_[ file ] +macro_name := CMC_[ lib ]_[ collection ]_[ part ]_[ access ]_[ file ] lib := CMC | COR | DEV | EXT | INT | SAC | TSC collection := BITSET | DEQUE | HASHBIDIMAP | ... | TREEMULTISET | TREESET part := CORE | ITER | INIT | ... | SETF | NODE +access := PUBLIC | PRIVATE file := HEADER | SOURCE ``` @@ -157,13 +158,6 @@ Every macro is suffixed by `CMC` and each section is separated by an underscore * __documentation__ - The markdowns used by [mdBook](https://github.com/rust-lang/mdBook) to generate the website * __examples__ - Examples using the C Macro Collections Library * __src__ - All headers part of the C Macro Collections Library - * __cmc__ - The main C Macro Collections Library - * __cor__ - Core includes in the C Macro Collections Library - * __ext__ - Extensions to the CMC, SAC and TSC collections - * __int__ - Integrations between Collections - * __sac__ - Statically Allocated Collections - * __tsc__ - Thread Safe Collections - * __utl__ - Utilities like ForEach macros, logging, etc * __macro\_collections.h__ - Master header containing all collections and utilities * __tests__ - Where all tests are hosted diff --git a/examples/example.c b/examples/example.c index 527d78d..bf1ca90 100644 --- a/examples/example.c +++ b/examples/example.c @@ -12,7 +12,7 @@ // needs to be generated first. Then, we can add other parts after. This macro // does all of that for us. The STR part will provide us with a function that // will be used later. -C_MACRO_COLLECTIONS_GEN(CMC, LIST, MY_LIST_PARAMS, (STR)) +C_MACRO_COLLECTIONS_EXTENDED(CMC, LIST, MY_LIST_PARAMS, (STR)) int main(void) { diff --git a/src/ext_cmc_bitset.h b/src/ext_cmc_bitset.h index 4c713ff..7966ee6 100644 --- a/src/ext_cmc_bitset.h +++ b/src/ext_cmc_bitset.h @@ -18,13 +18,15 @@ */ #define CMC_EXT_CMC_BITSET_PARTS PLACEHOLDER -#define CMC_EXT_CMC_BITSET_PLACEHOLDER(PARAMS) +#define CMC_EXT_CMC_BITSET_PLACEHOLDER(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_BITSET_PLACEHOLDER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER(PARAMS) +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_PUBLIC_HEADER(PARAMS) -#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE(PARAMS) +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_PUBLIC_SOURCE(PARAMS) -#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER_(PFX, SNAME, V) -#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE_(PFX, SNAME, V) +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_PRIVATE_HEADER(PARAMS) + +#define CMC_EXT_CMC_BITSET_PLACEHOLDER_PRIVATE_SOURCE(PARAMS) #endif /* CMC_EXT_CMC_BITSET_H */ diff --git a/src/ext_cmc_deque.h b/src/ext_cmc_deque.h index 622f359..1e59c90 100644 --- a/src/ext_cmc_deque.h +++ b/src/ext_cmc_deque.h @@ -23,17 +23,24 @@ * * The part 'INIT' gives a new way of initializing a collection. The collection * struct is not heap allocated, only its internal structure (nodes, buffers). + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_DEQUE_INIT_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_INIT_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_INIT_PUBLIC_SOURCE(PARAMS) \ CMC_EXT_CMC_DEQUE_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) +/* INIT Extension can't be used with opaque struct */ +#define CMC_EXT_CMC_DEQUE_INIT_PRIVATE_HEADER(PARAMS) +#define CMC_EXT_CMC_DEQUE_INIT_PRIVATE_SOURCE(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); \ @@ -98,15 +105,24 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_DEQUE_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_DEQUE_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_DEQUE_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \ @@ -363,15 +379,24 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_DEQUE_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_DEQUE_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_DEQUE_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_DEQUE_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/macro_collections.h b/src/macro_collections.h index 73c4654..9fe5cb9 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -16,9 +16,10 @@ * from any given sub-library. They are: * * - C_MACRO_COLLECTIONS - * - C_MACRO_COLLECTIONS_GEN - * - C_MACRO_COLLECTIONS_GEN_HEADER - * - C_MACRO_COLLECTIONS_GEN_SOURCE + * - C_MACRO_COLLECTIONS_INLINE + * - C_MACRO_COLLECTIONS_EXTENDED + * - C_MACRO_COLLECTIONS_EXTENDED_HEADER + * - C_MACRO_COLLECTIONS_EXTENDED_SOURCE * - C_MACRO_COLLECTIONS_ALL * - C_MACRO_COLLECTIONS_ALL_HEADER * - C_MACRO_COLLECTIONS_ALL_SOURCE @@ -88,15 +89,32 @@ * \param LIB The collection's sub-library * \param COLLECTION The name of the collection in all uppercase * \param PART The part of the collection (either CORE or one available at EXT) + * \param ACCESS Either PUBLIC or PRIVATE * \param FILE Either HEADER or SOURCE * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE)(PARAMS) -#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE) CMC_##LIB##_##COLLECTION##_##PART##_##FILE +#define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, ACCESS, FILE)(PARAMS) + +#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, ACCESS, FILE) \ + CMC_##LIB##_##COLLECTION##_##PART##_##ACCESS##_##FILE /** - * C_MACRO_COLLECTIONS_GEN + * C_MACRO_COLLECTIONS_INLINE + * + * Generates both HEADER and SOURCE one after the other of a certain PART of a certain LIB. + * + * \param LIB The collection's sub-library + * \param COLLECTION The name of the collection in all uppercase + * \param PART The part of the collection (either CORE or one available at EXT) + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) + */ +#define C_MACRO_COLLECTIONS_INLINE(LIB, COLLECTION, PART, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, PUBLIC, HEADER, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, PUBLIC, SOURCE, PARAMS) + +/** + * C_MACRO_COLLECTIONS_EXTENDED * * Generate the CORE of a collection along with one or more part from EXT. The * headers are generated first, then the source code. @@ -106,37 +124,39 @@ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) * \param PARTS A non-empty tuple of all desired EXT parts */ -#define C_MACRO_COLLECTIONS_GEN(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) +#define C_MACRO_COLLECTIONS_EXTENDED(LIB, COLLECTION, PARAMS, PARTS) \ + C_MACRO_COLLECTIONS_EXTENDED_HEADER(LIB, COLLECTION, PUBLIC, PARAMS, PARTS) \ + C_MACRO_COLLECTIONS_EXTENDED_SOURCE(LIB, COLLECTION, PUBLIC, PARAMS, PARTS) /** - * C_MACRO_COLLECTIONS_GEN_HEADER + * C_MACRO_COLLECTIONS_EXTENDED_HEADER * * Generate all headers of CORE and the specified header parts of a collection. * * \param LIB The collection's sub-library * \param COLLECTION The name of the collection in all uppercase + * \param ACCESS Either PUBLIC or PRIVATE * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) * \param PARTS A non-empty tuple of all desired EXT parts */ -#define C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, HEADER, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, CMC_EVAL PARTS) +#define C_MACRO_COLLECTIONS_EXTENDED_HEADER(LIB, COLLECTION, ACCESS, PARAMS, PARTS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, ACCESS, HEADER, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, ACCESS, HEADER, PARAMS, CMC_EVAL PARTS) /** - * C_MACRO_COLLECTIONS_GEN_SOURCE + * C_MACRO_COLLECTIONS_EXTENDED_SOURCE * * Generate all sources of CORE and the specified source parts of a collection. * * \param LIB The collection's sub-library * \param COLLECTION The name of the collection in all uppercase + * \param ACCESS Either PUBLIC or PRIVATE * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) * \param PARTS A non-empty tuple of all desired EXT parts */ -#define C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, SOURCE, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, CMC_EVAL PARTS) +#define C_MACRO_COLLECTIONS_EXTENDED_SOURCE(LIB, COLLECTION, ACCESS, PARAMS, PARTS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, ACCESS, SOURCE, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, ACCESS, SOURCE, PARAMS, CMC_EVAL PARTS) /** * C_MACRO_COLLECTIONS_ALL @@ -146,11 +166,11 @@ * * \param LIB The collection's library * \param COLLECTION The name of the collection in all uppercase - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ #define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \ - C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \ - C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) + C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PUBLIC, PARAMS) \ + C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PUBLIC, PARAMS) /** * C_MACRO_COLLECTIONS_ALL_HEADER @@ -159,11 +179,12 @@ * * \param LIB The collection's library * \param COLLECTION The name of the collection in all uppercase - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V + * \param ACCESS Either PUBLIC or PRIVATE + * \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_PUBLIC, HEADER, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) +#define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, ACCESS, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, ACCESS, HEADER, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, ACCESS, HEADER, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) /** * C_MACRO_COLLECTIONS_ALL_SOURCE @@ -172,11 +193,12 @@ * * \param LIB The collection's library * \param COLLECTION The name of the collection in all uppercase + * \param ACCESS Either PUBLIC or PRIVATE * \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_PUBLIC, SOURCE, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) +#define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, ACCESS, PARAMS) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, ACCESS, SOURCE, PARAMS) \ + CMC_MAP(CMC_(EXT_, LIB), COLLECTION, ACCESS, SOURCE, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) /** * C_MACRO_COLLECTIONS_PARTS @@ -209,40 +231,37 @@ 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, ...) \ +#define CMC_MAP(LIB, COLLECTION, ACCESS, FILE, PARAMS, ...) \ CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \ - (LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) + (LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, PART, ...) -#define CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_10(LIB, COLLECTION, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \ - CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_9(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_8(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_8(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_7(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_7(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_6(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_6(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_5(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_5(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_4(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_4(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_3(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_3(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_2(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_2(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_1(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_1(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ + C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ + CMC_MAP_0(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) +#define CMC_MAP_0(LIB, COLLECTION, ACCESS, FILE, PARAMS, ...) #endif /* CMC_MACRO_COLLECTIONS_H */ From bd3198adf5af3bb83e288dceacc495e95b5c209b Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 2 Oct 2020 22:06:21 -0300 Subject: [PATCH 15/20] New architecture somewhat done --- src/ext_cmc_deque.h | 9 ++---- src/ext_cmc_hashbidimap.h | 21 ++++++++++--- src/ext_cmc_hashmap.h | 64 ++++++++++++++++++++++++++++---------- src/ext_cmc_hashmultimap.h | 42 +++++++++++++++++++------ src/ext_cmc_hashmultiset.h | 57 ++++++++++++++++++++++++--------- src/ext_cmc_hashset.h | 57 ++++++++++++++++++++++++--------- src/ext_cmc_heap.h | 39 +++++++++++++++++------ src/ext_cmc_intervalheap.h | 38 ++++++++++++++++------ src/ext_cmc_linkedlist.h | 57 ++++++++++++++++++++++++--------- src/ext_cmc_list.h | 54 +++++++++++++++++++++++--------- src/ext_cmc_queue.h | 36 +++++++++++++++------ src/ext_cmc_sortedlist.h | 38 ++++++++++++++++------ src/ext_cmc_stack.h | 36 +++++++++++++++------ src/ext_cmc_treemap.h | 42 +++++++++++++++++++------ src/ext_cmc_treeset.h | 57 ++++++++++++++++++++++++--------- src/macro_collections.h | 3 +- 16 files changed, 475 insertions(+), 175 deletions(-) diff --git a/src/ext_cmc_deque.h b/src/ext_cmc_deque.h index 1e59c90..81c99a3 100644 --- a/src/ext_cmc_deque.h +++ b/src/ext_cmc_deque.h @@ -28,8 +28,7 @@ * \param FILE Either HEADER or SOURCE * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_DEQUE_INIT(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_DEQUE_INIT_, ACCESS), CMC_(_, FILE))(PARAMS) +#define CMC_EXT_CMC_DEQUE_INIT(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_DEQUE_INIT_, ACCESS), CMC_(_, FILE))(PARAMS) #define CMC_EXT_CMC_DEQUE_INIT_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -110,8 +109,7 @@ * \param FILE Either HEADER or SOURCE * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_DEQUE_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_DEQUE_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) +#define CMC_EXT_CMC_DEQUE_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_DEQUE_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) #define CMC_EXT_CMC_DEQUE_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) @@ -384,8 +382,7 @@ * \param FILE Either HEADER or SOURCE * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_DEQUE_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_DEQUE_STR_, ACCESS), CMC_(_, FILE))(PARAMS) +#define CMC_EXT_CMC_DEQUE_STR(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_DEQUE_STR_, ACCESS), CMC_(_, FILE))(PARAMS) #define CMC_EXT_CMC_DEQUE_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) diff --git a/src/ext_cmc_hashbidimap.h b/src/ext_cmc_hashbidimap.h index 9eda3fb..938cf98 100644 --- a/src/ext_cmc_hashbidimap.h +++ b/src/ext_cmc_hashbidimap.h @@ -20,16 +20,27 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_HASHBIDIMAP_STR(PARAMS) \ - CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE(PARAMS) +#define CMC_EXT_CMC_HASHBIDIMAP_STR(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHBIDIMAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHBIDIMAP_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_HASHBIDIMAP_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHBIDIMAP_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHBIDIMAP_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) diff --git a/src/ext_cmc_hashmap.h b/src/ext_cmc_hashmap.h index 151c267..08df9dd 100644 --- a/src/ext_cmc_hashmap.h +++ b/src/ext_cmc_hashmap.h @@ -21,18 +21,26 @@ /** * INIT * - * The part 'INIT' gives a new way of initializing a collection. The collection - * struct is not heap allocated, only its internal structure (nodes, buffers). + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHMAP_INIT_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHMAP_INIT_PUBLIC_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) \ +#define CMC_EXT_CMC_HASHMAP_INIT_PUBLIC_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_PRIVATE_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_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) @@ -116,16 +124,27 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHMAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHMAP_ITER_PUBLIC_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) \ +#define CMC_EXT_CMC_HASHMAP_ITER_PUBLIC_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_PRIVATE_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_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) @@ -441,16 +460,27 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHMAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHMAP_STR_PUBLIC_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) \ +#define CMC_EXT_CMC_HASHMAP_STR_PUBLIC_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_PRIVATE_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_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) diff --git a/src/ext_cmc_hashmultimap.h b/src/ext_cmc_hashmultimap.h index 8e14619..0b4b0aa 100644 --- a/src/ext_cmc_hashmultimap.h +++ b/src/ext_cmc_hashmultimap.h @@ -20,16 +20,27 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHMULTIMAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_PUBLIC_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) \ +#define CMC_EXT_CMC_HASHMULTIMAP_ITER_PUBLIC_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_PRIVATE_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_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) @@ -370,16 +381,27 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHMULTIMAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTIMAP_STR_PUBLIC_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) \ +#define CMC_EXT_CMC_HASHMULTIMAP_STR_PUBLIC_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_PRIVATE_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_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) diff --git a/src/ext_cmc_hashmultiset.h b/src/ext_cmc_hashmultiset.h index 36e0f18..9d0994c 100644 --- a/src/ext_cmc_hashmultiset.h +++ b/src/ext_cmc_hashmultiset.h @@ -20,15 +20,24 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHMULTISET_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(PFX, SNAME, V) \ @@ -334,15 +343,24 @@ /** * SETF + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHMULTISET_SETF_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_SETF_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_SETF_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_SETF_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_SETF_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(PFX, SNAME, V) \ @@ -617,15 +635,24 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHMULTISET_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_HASHMULTISET_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHMULTISET_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/ext_cmc_hashset.h b/src/ext_cmc_hashset.h index d33eb39..5b100c9 100644 --- a/src/ext_cmc_hashset.h +++ b/src/ext_cmc_hashset.h @@ -20,15 +20,24 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHSET_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHSET_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHSET_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHSET_ITER_HEADER_(PFX, SNAME, V) \ @@ -325,15 +334,24 @@ /** * SETF + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHSET_SETF_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_SETF_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_HASHSET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_SETF_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_SETF_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_SETF_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHSET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHSET_SETF_HEADER_(PFX, SNAME, V) \ @@ -591,15 +609,24 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_HASHSET_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HASHSET_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HASHSET_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_HASHSET_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HASHSET_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HASHSET_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/ext_cmc_heap.h b/src/ext_cmc_heap.h index 822920d..455f6fa 100644 --- a/src/ext_cmc_heap.h +++ b/src/ext_cmc_heap.h @@ -18,14 +18,25 @@ */ #define CMC_EXT_CMC_HEAP_PARTS ITER, STR -#define CMC_EXT_CMC_HEAP_ITER(PARAMS) \ - CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS) +/** + * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) + */ +#define CMC_EXT_CMC_HEAP_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_HEAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HEAP_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_HEAP_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HEAP_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_HEAP_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \ @@ -244,15 +255,23 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_HEAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_HEAP_STR_PUBLIC_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) \ +#define CMC_EXT_CMC_HEAP_STR_PUBLIC_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_PRIVATE_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_PRIVATE_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) \ diff --git a/src/ext_cmc_intervalheap.h b/src/ext_cmc_intervalheap.h index fb37b99..be27130 100644 --- a/src/ext_cmc_intervalheap.h +++ b/src/ext_cmc_intervalheap.h @@ -20,15 +20,24 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_INTERVALHEAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_INTERVALHEAP_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_INTERVALHEAP_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \ @@ -247,15 +256,24 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_INTERVALHEAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_INTERVALHEAP_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_INTERVALHEAP_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_INTERVALHEAP_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/ext_cmc_linkedlist.h b/src/ext_cmc_linkedlist.h index a531128..66d4e38 100644 --- a/src/ext_cmc_linkedlist.h +++ b/src/ext_cmc_linkedlist.h @@ -20,15 +20,24 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_LINKEDLIST_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(PFX, SNAME, V) \ @@ -274,15 +283,24 @@ /** * NODE + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_LINKEDLIST_NODE_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_NODE_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_NODE_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_NODE_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_NODE_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(PFX, SNAME, V) \ @@ -504,15 +522,24 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_LINKEDLIST_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_LINKEDLIST_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LINKEDLIST_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/ext_cmc_list.h b/src/ext_cmc_list.h index 269adfd..027caed 100644 --- a/src/ext_cmc_list.h +++ b/src/ext_cmc_list.h @@ -20,15 +20,23 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_LIST_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_LIST_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_LIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_LIST_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_LIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_LIST_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_LIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_LIST_ITER_HEADER_(PFX, SNAME, V) \ @@ -253,15 +261,23 @@ /** * SEQ + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_LIST_SEQ_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \ +#define CMC_EXT_CMC_LIST_SEQ_PUBLIC_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) \ +#define CMC_EXT_CMC_LIST_SEQ_PUBLIC_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_PRIVATE_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_PRIVATE_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) \ @@ -433,15 +449,23 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_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(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_LIST_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_LIST_STR_PUBLIC_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) \ +#define CMC_EXT_CMC_LIST_STR_PUBLIC_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_PRIVATE_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_PRIVATE_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) \ diff --git a/src/ext_cmc_queue.h b/src/ext_cmc_queue.h index 378e54c..9158ba3 100644 --- a/src/ext_cmc_queue.h +++ b/src/ext_cmc_queue.h @@ -20,15 +20,23 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_QUEUE_ITER(PARAMS) \ - CMC_EXT_CMC_QUEUE_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_QUEUE_ITER_SOURCE(PARAMS) +#define CMC_EXT_CMC_QUEUE_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_QUEUE_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_QUEUE_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_QUEUE_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_QUEUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_QUEUE_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_QUEUE_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_QUEUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_QUEUE_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_QUEUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_QUEUE_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_QUEUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_QUEUE_ITER_HEADER_(PFX, SNAME, V) \ @@ -285,15 +293,23 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_QUEUE_STR(PARAMS) \ - CMC_EXT_CMC_QUEUE_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_QUEUE_STR_SOURCE(PARAMS) +#define CMC_EXT_CMC_QUEUE_STR(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_QUEUE_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_QUEUE_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_QUEUE_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_QUEUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_QUEUE_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_QUEUE_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_QUEUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_QUEUE_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_QUEUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_QUEUE_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_QUEUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_QUEUE_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/ext_cmc_sortedlist.h b/src/ext_cmc_sortedlist.h index 8cd7487..576f8d8 100644 --- a/src/ext_cmc_sortedlist.h +++ b/src/ext_cmc_sortedlist.h @@ -20,15 +20,24 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_SORTEDLIST_ITER(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE(PARAMS) +#define CMC_EXT_CMC_SORTEDLIST_ITER(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_SORTEDLIST_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_SORTEDLIST_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_SORTEDLIST_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_SORTEDLIST_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_SORTEDLIST_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_SORTEDLIST_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(PFX, SNAME, V) \ @@ -248,15 +257,24 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_SORTEDLIST_STR(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_STR_SOURCE(PARAMS) +#define CMC_EXT_CMC_SORTEDLIST_STR(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_SORTEDLIST_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_SORTEDLIST_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_SORTEDLIST_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_SORTEDLIST_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_SORTEDLIST_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_SORTEDLIST_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_SORTEDLIST_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/ext_cmc_stack.h b/src/ext_cmc_stack.h index 4bba905..bd47d2f 100644 --- a/src/ext_cmc_stack.h +++ b/src/ext_cmc_stack.h @@ -20,15 +20,23 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_STACK_ITER(PARAMS) \ - CMC_EXT_CMC_STACK_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_STACK_ITER_SOURCE(PARAMS) +#define CMC_EXT_CMC_STACK_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_STACK_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_STACK_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_STACK_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_STACK_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_STACK_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_STACK_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_STACK_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_STACK_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_STACK_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_STACK_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_STACK_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_STACK_ITER_HEADER_(PFX, SNAME, V) \ @@ -256,15 +264,23 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_STACK_STR(PARAMS) \ - CMC_EXT_CMC_STACK_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_STACK_STR_SOURCE(PARAMS) +#define CMC_EXT_CMC_STACK_STR(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_STACK_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_STACK_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_STACK_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_STACK_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_STACK_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_STACK_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_STACK_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_STACK_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_STACK_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_STACK_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_STACK_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_STACK_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/ext_cmc_treemap.h b/src/ext_cmc_treemap.h index f78fbdb..ad3f38f 100644 --- a/src/ext_cmc_treemap.h +++ b/src/ext_cmc_treemap.h @@ -20,16 +20,27 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_TREEMAP_ITER(PARAMS) \ - CMC_EXT_CMC_TREEMAP_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_TREEMAP_ITER_SOURCE(PARAMS) +#define CMC_EXT_CMC_TREEMAP_ITER(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_TREEMAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_TREEMAP_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_TREEMAP_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_TREEMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_TREEMAP_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_TREEMAP_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREEMAP_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_TREEMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREEMAP_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) @@ -346,16 +357,27 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_TREEMAP_STR(PARAMS) \ - CMC_EXT_CMC_TREEMAP_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_TREEMAP_STR_SOURCE(PARAMS) +#define CMC_EXT_CMC_TREEMAP_STR(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_TREEMAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_TREEMAP_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_TREEMAP_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_TREEMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_TREEMAP_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_TREEMAP_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREEMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREEMAP_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_TREEMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ + CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREEMAP_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_TREEMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ CMC_PARAM_V(PARAMS)) diff --git a/src/ext_cmc_treeset.h b/src/ext_cmc_treeset.h index 5fffde9..8320a6c 100644 --- a/src/ext_cmc_treeset.h +++ b/src/ext_cmc_treeset.h @@ -20,15 +20,24 @@ /** * ITER + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_TREESET_ITER(PARAMS) \ - CMC_EXT_CMC_TREESET_ITER_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_ITER_SOURCE(PARAMS) +#define CMC_EXT_CMC_TREESET_ITER(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_TREESET_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_TREESET_ITER_HEADER(PARAMS) \ +#define CMC_EXT_CMC_TREESET_ITER_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_TREESET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_TREESET_ITER_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_TREESET_ITER_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREESET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_ITER_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_ITER_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_TREESET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_TREESET_ITER_HEADER_(PFX, SNAME, V) \ @@ -326,15 +335,24 @@ /** * SETF + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_TREESET_SETF(PARAMS) \ - CMC_EXT_CMC_TREESET_SETF_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_SETF_SOURCE(PARAMS) +#define CMC_EXT_CMC_TREESET_SETF(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_TREESET_SETF_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_TREESET_SETF_HEADER(PARAMS) \ +#define CMC_EXT_CMC_TREESET_SETF_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_TREESET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_TREESET_SETF_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_TREESET_SETF_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_SETF_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_SETF_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_TREESET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_TREESET_SETF_HEADER_(PFX, SNAME, V) \ @@ -559,15 +577,24 @@ /** * STR + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) */ -#define CMC_EXT_CMC_TREESET_STR(PARAMS) \ - CMC_EXT_CMC_TREESET_STR_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_STR_SOURCE(PARAMS) +#define CMC_EXT_CMC_TREESET_STR(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_CMC_TREESET_STR_, ACCESS), CMC_(_, FILE))(PARAMS) -#define CMC_EXT_CMC_TREESET_STR_HEADER(PARAMS) \ +#define CMC_EXT_CMC_TREESET_STR_PUBLIC_HEADER(PARAMS) \ CMC_EXT_CMC_TREESET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_TREESET_STR_SOURCE(PARAMS) \ +#define CMC_EXT_CMC_TREESET_STR_PUBLIC_SOURCE(PARAMS) \ + CMC_EXT_CMC_TREESET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_STR_PRIVATE_HEADER(PARAMS) \ + CMC_EXT_CMC_TREESET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_EXT_CMC_TREESET_STR_PRIVATE_SOURCE(PARAMS) \ CMC_EXT_CMC_TREESET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) #define CMC_EXT_CMC_TREESET_STR_HEADER_(PFX, SNAME, V) \ diff --git a/src/macro_collections.h b/src/macro_collections.h index 9fe5cb9..a4d1e2f 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -96,8 +96,7 @@ #define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, ACCESS, FILE)(PARAMS) -#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, ACCESS, FILE) \ - CMC_##LIB##_##COLLECTION##_##PART##_##ACCESS##_##FILE +#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, ACCESS, FILE) CMC_##LIB##_##COLLECTION##_##PART##_##ACCESS##_##FILE /** * C_MACRO_COLLECTIONS_INLINE From 3a1d2442860eb86b4f2880fa1b4b7f2aaa607760 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Fri, 2 Oct 2020 22:17:40 -0300 Subject: [PATCH 16/20] Possibly fixing tests --- autogen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autogen.py b/autogen.py index 504fdb8..7c8f247 100644 --- a/autogen.py +++ b/autogen.py @@ -241,7 +241,7 @@ def expand_code(): {UNIQUE_FLAG} - C_MACRO_COLLECTIONS_ALL_{ftype}({data['LIB']}, {data['COLLECTION']}, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) + C_MACRO_COLLECTIONS_ALL_{ftype}({data['LIB']}, {data['COLLECTION']}, PUBLIC, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) {UNIQUE_FLAG} ''') From dba782ccd6254436e8fd72fb9342dabaaa7d3f2e Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Sun, 4 Oct 2020 23:00:48 -0300 Subject: [PATCH 17/20] Adding License to src files --- src/cmc_bitset.h | 24 ++++++++++++++++++++++++ src/cmc_deque.h | 24 ++++++++++++++++++++++++ src/cmc_hashbidimap.h | 24 ++++++++++++++++++++++++ src/cmc_hashmap.h | 24 ++++++++++++++++++++++++ src/cmc_hashmultimap.h | 24 ++++++++++++++++++++++++ src/cmc_hashmultiset.h | 24 ++++++++++++++++++++++++ src/cmc_hashset.h | 24 ++++++++++++++++++++++++ src/cmc_heap.h | 24 ++++++++++++++++++++++++ src/cmc_intervalheap.h | 24 ++++++++++++++++++++++++ src/cmc_linkedlist.h | 24 ++++++++++++++++++++++++ src/cmc_list.h | 24 ++++++++++++++++++++++++ src/cmc_queue.h | 24 ++++++++++++++++++++++++ src/cmc_sortedlist.h | 24 ++++++++++++++++++++++++ src/cmc_stack.h | 24 ++++++++++++++++++++++++ src/cmc_treemap.h | 24 ++++++++++++++++++++++++ src/cmc_treeset.h | 24 ++++++++++++++++++++++++ src/cor_alloc.h | 24 ++++++++++++++++++++++++ src/cor_bitset.h | 24 ++++++++++++++++++++++++ src/cor_callbacks.h | 24 ++++++++++++++++++++++++ src/cor_core.h | 24 ++++++++++++++++++++++++ src/cor_flags.h | 24 ++++++++++++++++++++++++ src/cor_ftable.h | 24 ++++++++++++++++++++++++ src/cor_hashtable.h | 24 ++++++++++++++++++++++++ src/cor_heap.h | 24 ++++++++++++++++++++++++ src/ext_cmc_bitset.h | 24 ++++++++++++++++++++++++ src/ext_cmc_deque.h | 24 ++++++++++++++++++++++++ src/ext_cmc_hashbidimap.h | 24 ++++++++++++++++++++++++ src/ext_cmc_hashmap.h | 24 ++++++++++++++++++++++++ src/ext_cmc_hashmultimap.h | 24 ++++++++++++++++++++++++ src/ext_cmc_hashmultiset.h | 24 ++++++++++++++++++++++++ src/ext_cmc_hashset.h | 24 ++++++++++++++++++++++++ src/ext_cmc_heap.h | 24 ++++++++++++++++++++++++ src/ext_cmc_intervalheap.h | 24 ++++++++++++++++++++++++ src/ext_cmc_linkedlist.h | 24 ++++++++++++++++++++++++ src/ext_cmc_list.h | 24 ++++++++++++++++++++++++ src/ext_cmc_queue.h | 24 ++++++++++++++++++++++++ src/ext_cmc_sortedlist.h | 24 ++++++++++++++++++++++++ src/ext_cmc_stack.h | 24 ++++++++++++++++++++++++ src/ext_cmc_treemap.h | 24 ++++++++++++++++++++++++ src/ext_cmc_treeset.h | 24 ++++++++++++++++++++++++ src/macro_collections.h | 24 ++++++++++++++++++++++++ src/utl_assert.h | 24 ++++++++++++++++++++++++ src/utl_foreach.h | 24 ++++++++++++++++++++++++ src/utl_futils.h | 24 ++++++++++++++++++++++++ src/utl_log.h | 24 ++++++++++++++++++++++++ src/utl_mutex.h | 24 ++++++++++++++++++++++++ src/utl_test.h | 24 ++++++++++++++++++++++++ src/utl_thread.h | 24 ++++++++++++++++++++++++ src/utl_timer.h | 24 ++++++++++++++++++++++++ 49 files changed, 1176 insertions(+) diff --git a/src/cmc_bitset.h b/src/cmc_bitset.h index 3fb2a91..17d1bca 100644 --- a/src/cmc_bitset.h +++ b/src/cmc_bitset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_bitset.h * diff --git a/src/cmc_deque.h b/src/cmc_deque.h index e2edf40..e3a14d6 100644 --- a/src/cmc_deque.h +++ b/src/cmc_deque.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_deque.h * diff --git a/src/cmc_hashbidimap.h b/src/cmc_hashbidimap.h index 660301c..dad8539 100644 --- a/src/cmc_hashbidimap.h +++ b/src/cmc_hashbidimap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_hashbidimap.h * diff --git a/src/cmc_hashmap.h b/src/cmc_hashmap.h index 4380585..ff7ed26 100644 --- a/src/cmc_hashmap.h +++ b/src/cmc_hashmap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_hashmap.h * diff --git a/src/cmc_hashmultimap.h b/src/cmc_hashmultimap.h index 8cd0272..9f6cd36 100644 --- a/src/cmc_hashmultimap.h +++ b/src/cmc_hashmultimap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_hashmultimap.h * diff --git a/src/cmc_hashmultiset.h b/src/cmc_hashmultiset.h index d8587b2..05ddcdc 100644 --- a/src/cmc_hashmultiset.h +++ b/src/cmc_hashmultiset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_hashmultiset.h * diff --git a/src/cmc_hashset.h b/src/cmc_hashset.h index 14f4ae3..8965fb8 100644 --- a/src/cmc_hashset.h +++ b/src/cmc_hashset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_hashset.h * diff --git a/src/cmc_heap.h b/src/cmc_heap.h index b0933f2..4a0e1d0 100644 --- a/src/cmc_heap.h +++ b/src/cmc_heap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_heap.h * diff --git a/src/cmc_intervalheap.h b/src/cmc_intervalheap.h index 19db17c..2be1102 100644 --- a/src/cmc_intervalheap.h +++ b/src/cmc_intervalheap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_intervalheap.h * diff --git a/src/cmc_linkedlist.h b/src/cmc_linkedlist.h index 13187ce..692269f 100644 --- a/src/cmc_linkedlist.h +++ b/src/cmc_linkedlist.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_linkedlist.h * diff --git a/src/cmc_list.h b/src/cmc_list.h index 3a9ce07..3e25c0a 100644 --- a/src/cmc_list.h +++ b/src/cmc_list.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_list.h * diff --git a/src/cmc_queue.h b/src/cmc_queue.h index a63f28b..f9aaf3a 100644 --- a/src/cmc_queue.h +++ b/src/cmc_queue.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_queue.h * diff --git a/src/cmc_sortedlist.h b/src/cmc_sortedlist.h index 5bdede8..4ccc9f5 100644 --- a/src/cmc_sortedlist.h +++ b/src/cmc_sortedlist.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_sortedlist.h * diff --git a/src/cmc_stack.h b/src/cmc_stack.h index d56dc8f..d922da4 100644 --- a/src/cmc_stack.h +++ b/src/cmc_stack.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_stack.h * diff --git a/src/cmc_treemap.h b/src/cmc_treemap.h index 8d23669..78ef338 100644 --- a/src/cmc_treemap.h +++ b/src/cmc_treemap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_treemap.h * diff --git a/src/cmc_treeset.h b/src/cmc_treeset.h index c80b393..2822016 100644 --- a/src/cmc_treeset.h +++ b/src/cmc_treeset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cmc_treeset.h * diff --git a/src/cor_alloc.h b/src/cor_alloc.h index d27cd98..b3d0eee 100644 --- a/src/cor_alloc.h +++ b/src/cor_alloc.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cor_alloc.h * diff --git a/src/cor_bitset.h b/src/cor_bitset.h index bbfa94f..a42e583 100644 --- a/src/cor_bitset.h +++ b/src/cor_bitset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cor_bitset.h * diff --git a/src/cor_callbacks.h b/src/cor_callbacks.h index 1601c77..4d21481 100644 --- a/src/cor_callbacks.h +++ b/src/cor_callbacks.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cor_callbacks.h * diff --git a/src/cor_core.h b/src/cor_core.h index f0d275e..09bbb74 100644 --- a/src/cor_core.h +++ b/src/cor_core.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cor_core.h * diff --git a/src/cor_flags.h b/src/cor_flags.h index d8fd3d2..bcbeb6a 100644 --- a/src/cor_flags.h +++ b/src/cor_flags.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cor_flags.h * diff --git a/src/cor_ftable.h b/src/cor_ftable.h index 21f38a3..206dd1f 100644 --- a/src/cor_ftable.h +++ b/src/cor_ftable.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cor_ftable.h * diff --git a/src/cor_hashtable.h b/src/cor_hashtable.h index a1b9c2c..816e07d 100644 --- a/src/cor_hashtable.h +++ b/src/cor_hashtable.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cor_hashtable.h * diff --git a/src/cor_heap.h b/src/cor_heap.h index d2fe693..b395fe9 100644 --- a/src/cor_heap.h +++ b/src/cor_heap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * cor_heap.h * diff --git a/src/ext_cmc_bitset.h b/src/ext_cmc_bitset.h index 7966ee6..3e431a4 100644 --- a/src/ext_cmc_bitset.h +++ b/src/ext_cmc_bitset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_bitset.h * diff --git a/src/ext_cmc_deque.h b/src/ext_cmc_deque.h index 81c99a3..af2b2d3 100644 --- a/src/ext_cmc_deque.h +++ b/src/ext_cmc_deque.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_deque.h * diff --git a/src/ext_cmc_hashbidimap.h b/src/ext_cmc_hashbidimap.h index 938cf98..89e7984 100644 --- a/src/ext_cmc_hashbidimap.h +++ b/src/ext_cmc_hashbidimap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_hashbidimap.h * diff --git a/src/ext_cmc_hashmap.h b/src/ext_cmc_hashmap.h index 08df9dd..57d0cdf 100644 --- a/src/ext_cmc_hashmap.h +++ b/src/ext_cmc_hashmap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_hashmap.h * diff --git a/src/ext_cmc_hashmultimap.h b/src/ext_cmc_hashmultimap.h index 0b4b0aa..e355397 100644 --- a/src/ext_cmc_hashmultimap.h +++ b/src/ext_cmc_hashmultimap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_hashmultimap.h * diff --git a/src/ext_cmc_hashmultiset.h b/src/ext_cmc_hashmultiset.h index 9d0994c..c3727f0 100644 --- a/src/ext_cmc_hashmultiset.h +++ b/src/ext_cmc_hashmultiset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_hashmultiset.h * diff --git a/src/ext_cmc_hashset.h b/src/ext_cmc_hashset.h index 5b100c9..41c5f3f 100644 --- a/src/ext_cmc_hashset.h +++ b/src/ext_cmc_hashset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_hashset.h * diff --git a/src/ext_cmc_heap.h b/src/ext_cmc_heap.h index 455f6fa..578b2c1 100644 --- a/src/ext_cmc_heap.h +++ b/src/ext_cmc_heap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_heap.h * diff --git a/src/ext_cmc_intervalheap.h b/src/ext_cmc_intervalheap.h index be27130..f75ef7c 100644 --- a/src/ext_cmc_intervalheap.h +++ b/src/ext_cmc_intervalheap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_intervalheap.h * diff --git a/src/ext_cmc_linkedlist.h b/src/ext_cmc_linkedlist.h index 66d4e38..40001b6 100644 --- a/src/ext_cmc_linkedlist.h +++ b/src/ext_cmc_linkedlist.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_linkedlist.h * diff --git a/src/ext_cmc_list.h b/src/ext_cmc_list.h index 027caed..6e683c3 100644 --- a/src/ext_cmc_list.h +++ b/src/ext_cmc_list.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_list.h * diff --git a/src/ext_cmc_queue.h b/src/ext_cmc_queue.h index 9158ba3..d411371 100644 --- a/src/ext_cmc_queue.h +++ b/src/ext_cmc_queue.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_queue.h * diff --git a/src/ext_cmc_sortedlist.h b/src/ext_cmc_sortedlist.h index 576f8d8..8d5189e 100644 --- a/src/ext_cmc_sortedlist.h +++ b/src/ext_cmc_sortedlist.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_sortedlist.h * diff --git a/src/ext_cmc_stack.h b/src/ext_cmc_stack.h index bd47d2f..145bf6e 100644 --- a/src/ext_cmc_stack.h +++ b/src/ext_cmc_stack.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_stack.h * diff --git a/src/ext_cmc_treemap.h b/src/ext_cmc_treemap.h index ad3f38f..5b2952f 100644 --- a/src/ext_cmc_treemap.h +++ b/src/ext_cmc_treemap.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_treemap.h * diff --git a/src/ext_cmc_treeset.h b/src/ext_cmc_treeset.h index 8320a6c..a4cb620 100644 --- a/src/ext_cmc_treeset.h +++ b/src/ext_cmc_treeset.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * ext_cmc_treeset.h * diff --git a/src/macro_collections.h b/src/macro_collections.h index a4d1e2f..dcfd29f 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * macro_collections.h * diff --git a/src/utl_assert.h b/src/utl_assert.h index 1ca4d56..db7b5ef 100644 --- a/src/utl_assert.h +++ b/src/utl_assert.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * utl_assert.h * diff --git a/src/utl_foreach.h b/src/utl_foreach.h index de0b2f4..f276225 100644 --- a/src/utl_foreach.h +++ b/src/utl_foreach.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * utl_foreach.h * diff --git a/src/utl_futils.h b/src/utl_futils.h index 8128148..206e1b6 100644 --- a/src/utl_futils.h +++ b/src/utl_futils.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * utl_futils.h * diff --git a/src/utl_log.h b/src/utl_log.h index 6100638..e874994 100644 --- a/src/utl_log.h +++ b/src/utl_log.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * utl_log.h * diff --git a/src/utl_mutex.h b/src/utl_mutex.h index 2d57d50..9bb9eef 100644 --- a/src/utl_mutex.h +++ b/src/utl_mutex.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * utl_mutex.h * diff --git a/src/utl_test.h b/src/utl_test.h index 75efd08..065fca0 100644 --- a/src/utl_test.h +++ b/src/utl_test.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * utl_test.h * diff --git a/src/utl_thread.h b/src/utl_thread.h index dfc9da0..345b9af 100644 --- a/src/utl_thread.h +++ b/src/utl_thread.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * utl_thread.h * diff --git a/src/utl_timer.h b/src/utl_timer.h index 8f75e97..98d7ed2 100644 --- a/src/utl_timer.h +++ b/src/utl_timer.h @@ -1,3 +1,27 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + /** * utl_timer.h * From 3d4733fd5fb89efdd6df91edca902db33a44319e Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Tue, 6 Oct 2020 18:53:20 -0300 Subject: [PATCH 18/20] SAC List --- src/cor_flags.h | 7 +- src/ext_sac_list.h | 56 ++++ src/macro_collections.h | 3 + src/sac_list.h | 559 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 622 insertions(+), 3 deletions(-) create mode 100644 src/ext_sac_list.h create mode 100644 src/sac_list.h diff --git a/src/cor_flags.h b/src/cor_flags.h index d8fd3d2..b783862 100644 --- a/src/cor_flags.h +++ b/src/cor_flags.h @@ -30,7 +30,8 @@ enum cmc_flags CMC_FLAG_DUPLICATE = 6, // Duplicate key or value CMC_FLAG_ERROR = 7, // Generic error, usually caused by algorithm error CMC_FLAG_THREAD = 8, // Generic error regarding threads - CMC_FLAG_MUTEX = 9 // Generic error regarding mutexes + CMC_FLAG_MUTEX = 9, // Generic error regarding mutexes + CMC_FLAG_FULL = 10, // When a collection that doesn't resize is full }; // clang-format on @@ -39,7 +40,7 @@ enum cmc_flags * * Maps the error codes to their character representation. */ -CMC_UNUSED static const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID", - "RANGE", "DUPLICATE", "ERROR", "THREAD", "MUTEX" }; +CMC_UNUSED static const char *cmc_flags_to_str[11] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID", + "RANGE", "DUPLICATE", "ERROR", "THREAD", "MUTEX", "FULL" }; #endif /* CMC_COR_FLAGS_H */ diff --git a/src/ext_sac_list.h b/src/ext_sac_list.h new file mode 100644 index 0000000..65f56a1 --- /dev/null +++ b/src/ext_sac_list.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * ext_sac_list.h + * + * Creation Date: 06/10/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +#ifndef CMC_EXT_SAC_LIST_H +#define CMC_EXT_SAC_LIST_H + +#include "cor_core.h" + +/** + * All the EXT parts of SAC List. + */ +#define CMC_EXT_SAC_LIST_PARTS PLACEHOLDER + +#define CMC_EXT_SAC_LIST_PLACEHOLDER(ACCESS, FILE, PARAMS) \ + CMC_(CMC_(CMC_EXT_SAC_LIST_PLACEHOLDER_, ACCESS), CMC_(_, FILE))(PARAMS) + +#define CMC_EXT_SAC_LIST_PLACEHOLDER_PUBLIC_HEADER(PARAMS) + +#define CMC_EXT_SAC_LIST_PLACEHOLDER_PUBLIC_SOURCE(PARAMS) + +#define CMC_EXT_SAC_LIST_PLACEHOLDER_PRIVATE_HEADER(PARAMS) + +#define CMC_EXT_SAC_LIST_PLACEHOLDER_PRIVATE_SOURCE(PARAMS) + +#endif /* CMC_EXT_SAC_LIST_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h index 9fe5cb9..589f70e 100644 --- a/src/macro_collections.h +++ b/src/macro_collections.h @@ -70,6 +70,9 @@ #include "ext_cmc_stack.h" /* Added in 07/06/2020 */ #include "ext_cmc_treemap.h" /* Added in 08/06/2020 */ #include "ext_cmc_treeset.h" /* Added in 08/06/2020 */ +#include "ext_sac_list.h" /* Added in 08/06/2020 */ + +#include "sac_list.h" /* Added in 06/10/2020 */ #include "utl_assert.h" /* Added in 27/06/2019 */ #include "utl_foreach.h" /* Added in 25/02/2019 */ diff --git a/src/sac_list.h b/src/sac_list.h new file mode 100644 index 0000000..d34955a --- /dev/null +++ b/src/sac_list.h @@ -0,0 +1,559 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * sac_list.h + * + * Creation Date: 06/10/2020 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * List + * + * A List that is stored in a fixed sized array. It works very much like a list + * but is not resizeable and doesn't make use of dynamic memory internally. + */ + +/* TODO : Remove all allocations */ + +#ifndef CMC_SAC_LIST_H +#define CMC_SAC_LIST_H + +/* ------------------------------------------------------------------------- + * Core functionalities of the C Macro Collections Library + * ------------------------------------------------------------------------- */ +#include "cor_core.h" + +/** + * Core List implementation + * + * \param ACCESS Either PUBLIC or PRIVATE + * \param FILE Either HEADER or SOURCE + * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) + */ +#define CMC_SAC_LIST_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_SAC_LIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) + +/* PRIVATE or PUBLIC solver */ +#define CMC_SAC_LIST_CORE_PUBLIC_HEADER(PARAMS) \ + CMC_SAC_LIST_CORE_STRUCT(PARAMS) \ + CMC_SAC_LIST_CORE_HEADER(PARAMS) + +#define CMC_SAC_LIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_SAC_LIST_CORE_SOURCE(PARAMS) + +#define CMC_SAC_LIST_CORE_PRIVATE_HEADER(PARAMS) \ + struct CMC_PARAM_SNAME(PARAMS); \ + CMC_SAC_LIST_CORE_HEADER(PARAMS) + +#define CMC_SAC_LIST_CORE_PRIVATE_SOURCE(PARAMS) \ + CMC_SAC_LIST_CORE_STRUCT(PARAMS) \ + CMC_SAC_LIST_CORE_SOURCE(PARAMS) + +/* Lowest level API */ +#define CMC_SAC_LIST_CORE_STRUCT(PARAMS) \ + CMC_SAC_LIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SIZE(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_SAC_LIST_CORE_HEADER(PARAMS) \ + CMC_SAC_LIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SIZE(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +#define CMC_SAC_LIST_CORE_SOURCE(PARAMS) \ + CMC_SAC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SIZE(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) + +/* ------------------------------------------------------------------------- + * Struct + * ------------------------------------------------------------------------- */ +#define CMC_SAC_LIST_CORE_STRUCT_(PFX, SIZE, SNAME, V) \ +\ + /* List Structure */ \ + struct SNAME \ + { \ + /* Dynamic array of elements */ \ + V buffer[SIZE]; \ +\ + /* 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; \ + }; + +/* ------------------------------------------------------------------------- + * Header + * ------------------------------------------------------------------------- */ +#define CMC_SAC_LIST_CORE_HEADER_(PFX, SIZE, SNAME, V) \ +\ + /* 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_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 */ \ + struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); + +/* ------------------------------------------------------------------------- + * Source + * ------------------------------------------------------------------------- */ +#define CMC_SAC_LIST_CORE_SOURCE_(PFX, SIZE, 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) \ + { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ +\ + if (!f_val) \ + return NULL; \ +\ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ +\ + struct SNAME *_list_ = alloc->calloc(1, sizeof(struct SNAME)); \ +\ + if (!_list_) \ + return NULL; \ +\ + _list_->f_val = f_val; \ + _list_->alloc = alloc; \ + CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ +\ + return _list_; \ + } \ +\ + void CMC_(PFX, _clear)(struct SNAME * _list_) \ + { \ + memset(_list_, 0, sizeof(struct SNAME)); \ + } \ +\ + 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_); \ + } \ +\ + void CMC_(PFX, _customize)(struct SNAME * _list_, \ + struct CMC_CALLBACKS_NAME * callbacks) \ + { \ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ +\ + 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_)) \ + {\ + _list_->flag = CMC_FLAG_FULL;\ + 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; \ +\ + CMC_CALLBACKS_CALL(_list_, 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_)) \ + {\ + _list_->flag = CMC_FLAG_FULL;\ + 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; \ +\ + CMC_CALLBACKS_CALL(_list_, create); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ + { \ + if (CMC_(PFX, _full)(_list_)) \ + {\ + _list_->flag = CMC_FLAG_FULL;\ + return false; \ + }\ +\ + _list_->buffer[_list_->count++] = value; \ + _list_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_list_, 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; \ +\ + CMC_CALLBACKS_CALL(_list_, 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; \ +\ + CMC_CALLBACKS_CALL(_list_, delete); \ +\ + return true; \ + } \ +\ + bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ + { \ + if (CMC_(PFX, _empty)(_list_)) \ + {\ + _list_->flag = CMC_FLAG_EMPTY; \ + return false; \ + }\ +\ + _list_->buffer[--_list_->count] = (V){ 0 }; \ + _list_->flag = CMC_FLAG_OK; \ +\ + CMC_CALLBACKS_CALL(_list_, 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; \ +\ + CMC_CALLBACKS_CALL(_list_, 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; \ +\ + CMC_CALLBACKS_CALL(_list_, 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; \ +\ + CMC_CALLBACKS_CALL(_list_, 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; \ +\ + CMC_CALLBACKS_CALL(_list_, 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; \ + } \ + } \ + } \ +\ + CMC_CALLBACKS_CALL(_list_, 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; \ + } \ + } \ +\ + CMC_CALLBACKS_CALL(_list_, read); \ +\ + return result; \ + } \ +\ + bool CMC_(PFX, _empty)(struct SNAME * _list_) \ + { \ + return _list_->count == 0; \ + } \ +\ + bool CMC_(PFX, _full)(struct SNAME * _list_) \ + { \ + return _list_->count >= SIZE; \ + } \ +\ + 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 <= SIZE; \ + } \ +\ + size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ + { \ + return SIZE; \ + } \ +\ + 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) \ + { \ + _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; \ + } + +#endif /* CMC_SAC_LIST_H */ From 09d1cb649deed77d731e997be33070f8cbd4af38 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 7 Oct 2020 15:02:27 -0300 Subject: [PATCH 19/20] Final touches to SAC List --- CHANGELOG | 4 ++++ src/sac_list.h | 59 +++++++++++++++----------------------------------- 2 files changed, 21 insertions(+), 42 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 120734c..35b0c76 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ # RELEASE.MAJOR.MINOR +0.25.0 + New Project Architecture - Files are no longer separated in folders, but rather prefixed by their sub-library + Added sac_list.h + 0.24.0 A lot of breaking changes, with the library more modular now Comeback of PUBLIC and PRIVATE for the CMC sub-library diff --git a/src/sac_list.h b/src/sac_list.h index d34955a..05dff79 100644 --- a/src/sac_list.h +++ b/src/sac_list.h @@ -102,9 +102,6 @@ \ /* 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; \ @@ -139,10 +136,8 @@ \ /* 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_); \ + 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_CALLBACKS_NAME * callbacks); \ void CMC_(PFX, _free)(struct SNAME * _list_); \ /* Customization of Allocation and Callbacks */ \ void CMC_(PFX, _customize)(struct SNAME * _list_, \ @@ -169,7 +164,7 @@ size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ int CMC_(PFX, _flag)(struct SNAME * _list_); \ /* Collection Utility */ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ + struct SNAME CMC_(PFX, _copy_of)(struct SNAME * _list_); \ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); /* ------------------------------------------------------------------------- @@ -180,38 +175,25 @@ /* Implementation Detail Functions */ \ /* None */ \ \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ + struct SNAME CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ { \ - return CMC_(PFX, _new_custom)(f_val, NULL, NULL); \ + return CMC_(PFX, _new_custom)(f_val, 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) \ + struct SNAME CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_CALLBACKS_NAME * callbacks) \ { \ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ \ if (!f_val) \ - return NULL; \ + return (struct SNAME) { .flag = CMC_FLAG_ERROR, 0 }; \ \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ + struct SNAME _list_ = { 0 }; \ \ - struct SNAME *_list_ = alloc->calloc(1, sizeof(struct SNAME)); \ -\ - if (!_list_) \ - return NULL; \ -\ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ + _list_.f_val = f_val; \ + CMC_CALLBACKS_ASSIGN(&_list_, callbacks); \ \ return _list_; \ } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - memset(_list_, 0, sizeof(struct SNAME)); \ - } \ \ void CMC_(PFX, _free)(struct SNAME * _list_) \ { \ @@ -221,7 +203,7 @@ _list_->f_val->free(_list_->buffer[i]); \ } \ \ - _list_->alloc->free(_list_); \ + memset(_list_, 0, sizeof(struct SNAME)); \ } \ \ void CMC_(PFX, _customize)(struct SNAME * _list_, \ @@ -512,28 +494,21 @@ return _list_->flag; \ } \ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ + struct SNAME CMC_(PFX, _copy_of)(struct SNAME * _list_) \ { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_list_->f_val, _list_->alloc, NULL); \ + struct SNAME result = CMC_(PFX, _new_custom)(_list_->f_val, NULL); \ \ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \ + 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]); \ + result.buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ } \ else \ - memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \ -\ - result->count = _list_->count; \ + memcpy(result.buffer, _list_->buffer, sizeof(V) * _list_->count); \ \ + result.count = _list_->count; \ _list_->flag = CMC_FLAG_OK; \ \ return result; \ From a7ee017bcd288e0a1521cba5d8aaf83a07a01b58 Mon Sep 17 00:00:00 2001 From: Leonardo Vencovsky Date: Wed, 7 Oct 2020 15:03:39 -0300 Subject: [PATCH 20/20] v0.25.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d689ff..8d24736 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@

License - Version + Version travis-ci codecov test_suit